From 81d61ac3da169ac8195a98fd1a3facb0380a62c8 Mon Sep 17 00:00:00 2001 From: Marco Cawthorne Date: Wed, 16 Oct 2024 22:52:27 -0700 Subject: [PATCH] multiprogs additions, decl integration, more of everything really --- .gitignore | 4 + Documentation/About.md | 57 + Documentation/Decl.md | 6 - Documentation/DoxygenLayout.xml | 238 + Documentation/Footer.html | 1 + Documentation/GettingStarted.md | 12 + Documentation/History.md | 2 +- Documentation/ReadMe.md | 86 +- Documentation/footer.html | 17 + Doxyfile | 11 +- Makefile | 10 +- README.md | 5 + base/engine.h | 10 +- base/resources.pk3dir/decls/def/player.def | 3 +- base/resources.pk3dir/default.cfg | 15 +- base/resources.pk3dir/fonts/centerprint.font | 2 + base/resources.pk3dir/gfx/flags16/CREDITS | 3 + base/resources.pk3dir/gfx/flags16/ad.png | Bin 0 -> 643 bytes base/resources.pk3dir/gfx/flags16/ae.png | Bin 0 -> 408 bytes base/resources.pk3dir/gfx/flags16/af.png | Bin 0 -> 604 bytes base/resources.pk3dir/gfx/flags16/ag.png | Bin 0 -> 591 bytes base/resources.pk3dir/gfx/flags16/ai.png | Bin 0 -> 643 bytes base/resources.pk3dir/gfx/flags16/al.png | Bin 0 -> 600 bytes base/resources.pk3dir/gfx/flags16/am.png | Bin 0 -> 497 bytes base/resources.pk3dir/gfx/flags16/an.png | Bin 0 -> 488 bytes base/resources.pk3dir/gfx/flags16/ao.png | Bin 0 -> 428 bytes base/resources.pk3dir/gfx/flags16/ar.png | Bin 0 -> 506 bytes base/resources.pk3dir/gfx/flags16/as.png | Bin 0 -> 647 bytes base/resources.pk3dir/gfx/flags16/at.png | Bin 0 -> 403 bytes base/resources.pk3dir/gfx/flags16/au.png | Bin 0 -> 673 bytes base/resources.pk3dir/gfx/flags16/aw.png | Bin 0 -> 524 bytes base/resources.pk3dir/gfx/flags16/ax.png | Bin 0 -> 663 bytes base/resources.pk3dir/gfx/flags16/az.png | Bin 0 -> 589 bytes base/resources.pk3dir/gfx/flags16/ba.png | Bin 0 -> 593 bytes base/resources.pk3dir/gfx/flags16/bb.png | Bin 0 -> 585 bytes base/resources.pk3dir/gfx/flags16/bd.png | Bin 0 -> 504 bytes base/resources.pk3dir/gfx/flags16/be.png | Bin 0 -> 449 bytes base/resources.pk3dir/gfx/flags16/bf.png | Bin 0 -> 497 bytes base/resources.pk3dir/gfx/flags16/bg.png | Bin 0 -> 462 bytes base/resources.pk3dir/gfx/flags16/bh.png | Bin 0 -> 457 bytes base/resources.pk3dir/gfx/flags16/bi.png | Bin 0 -> 675 bytes base/resources.pk3dir/gfx/flags16/bj.png | Bin 0 -> 486 bytes base/resources.pk3dir/gfx/flags16/bm.png | Bin 0 -> 611 bytes base/resources.pk3dir/gfx/flags16/bn.png | Bin 0 -> 639 bytes base/resources.pk3dir/gfx/flags16/bo.png | Bin 0 -> 500 bytes base/resources.pk3dir/gfx/flags16/br.png | Bin 0 -> 593 bytes base/resources.pk3dir/gfx/flags16/bs.png | Bin 0 -> 526 bytes base/resources.pk3dir/gfx/flags16/bt.png | Bin 0 -> 631 bytes base/resources.pk3dir/gfx/flags16/bv.png | Bin 0 -> 512 bytes base/resources.pk3dir/gfx/flags16/bw.png | Bin 0 -> 443 bytes base/resources.pk3dir/gfx/flags16/by.png | Bin 0 -> 514 bytes base/resources.pk3dir/gfx/flags16/bz.png | Bin 0 -> 600 bytes base/resources.pk3dir/gfx/flags16/ca.png | Bin 0 -> 628 bytes .../gfx/flags16/catalonia.png | Bin 0 -> 398 bytes base/resources.pk3dir/gfx/flags16/cc.png | Bin 0 -> 625 bytes base/resources.pk3dir/gfx/flags16/cd.png | Bin 0 -> 528 bytes base/resources.pk3dir/gfx/flags16/cf.png | Bin 0 -> 614 bytes base/resources.pk3dir/gfx/flags16/cg.png | Bin 0 -> 521 bytes base/resources.pk3dir/gfx/flags16/ch.png | Bin 0 -> 367 bytes base/resources.pk3dir/gfx/flags16/ci.png | Bin 0 -> 453 bytes base/resources.pk3dir/gfx/flags16/ck.png | Bin 0 -> 586 bytes base/resources.pk3dir/gfx/flags16/cl.png | Bin 0 -> 450 bytes base/resources.pk3dir/gfx/flags16/cm.png | Bin 0 -> 525 bytes base/resources.pk3dir/gfx/flags16/cn.png | Bin 0 -> 472 bytes base/resources.pk3dir/gfx/flags16/co.png | Bin 0 -> 483 bytes base/resources.pk3dir/gfx/flags16/cr.png | Bin 0 -> 477 bytes base/resources.pk3dir/gfx/flags16/cs.png | Bin 0 -> 439 bytes base/resources.pk3dir/gfx/flags16/cu.png | Bin 0 -> 563 bytes base/resources.pk3dir/gfx/flags16/cv.png | Bin 0 -> 529 bytes base/resources.pk3dir/gfx/flags16/cx.png | Bin 0 -> 608 bytes base/resources.pk3dir/gfx/flags16/cy.png | Bin 0 -> 428 bytes base/resources.pk3dir/gfx/flags16/cz.png | Bin 0 -> 476 bytes base/resources.pk3dir/gfx/flags16/de.png | Bin 0 -> 545 bytes base/resources.pk3dir/gfx/flags16/dj.png | Bin 0 -> 572 bytes base/resources.pk3dir/gfx/flags16/dk.png | Bin 0 -> 495 bytes base/resources.pk3dir/gfx/flags16/dm.png | Bin 0 -> 620 bytes base/resources.pk3dir/gfx/flags16/do.png | Bin 0 -> 508 bytes base/resources.pk3dir/gfx/flags16/dz.png | Bin 0 -> 582 bytes base/resources.pk3dir/gfx/flags16/ec.png | Bin 0 -> 500 bytes base/resources.pk3dir/gfx/flags16/ee.png | Bin 0 -> 429 bytes base/resources.pk3dir/gfx/flags16/eg.png | Bin 0 -> 465 bytes base/resources.pk3dir/gfx/flags16/eh.png | Bin 0 -> 508 bytes base/resources.pk3dir/gfx/flags16/england.png | Bin 0 -> 496 bytes base/resources.pk3dir/gfx/flags16/er.png | Bin 0 -> 653 bytes base/resources.pk3dir/gfx/flags16/es.png | Bin 0 -> 469 bytes base/resources.pk3dir/gfx/flags16/et.png | Bin 0 -> 592 bytes .../gfx/flags16/europeanunion.png | Bin 0 -> 479 bytes base/resources.pk3dir/gfx/flags16/fam.png | Bin 0 -> 532 bytes base/resources.pk3dir/gfx/flags16/fi.png | Bin 0 -> 489 bytes base/resources.pk3dir/gfx/flags16/fj.png | Bin 0 -> 610 bytes base/resources.pk3dir/gfx/flags16/fk.png | Bin 0 -> 648 bytes base/resources.pk3dir/gfx/flags16/fm.png | Bin 0 -> 552 bytes base/resources.pk3dir/gfx/flags16/fo.png | Bin 0 -> 474 bytes base/resources.pk3dir/gfx/flags16/fr.png | Bin 0 -> 545 bytes base/resources.pk3dir/gfx/flags16/ga.png | Bin 0 -> 489 bytes base/resources.pk3dir/gfx/flags16/gb.png | Bin 0 -> 599 bytes base/resources.pk3dir/gfx/flags16/gd.png | Bin 0 -> 637 bytes base/resources.pk3dir/gfx/flags16/ge.png | Bin 0 -> 594 bytes base/resources.pk3dir/gfx/flags16/gf.png | Bin 0 -> 545 bytes base/resources.pk3dir/gfx/flags16/gh.png | Bin 0 -> 490 bytes base/resources.pk3dir/gfx/flags16/gi.png | Bin 0 -> 463 bytes base/resources.pk3dir/gfx/flags16/gl.png | Bin 0 -> 470 bytes base/resources.pk3dir/gfx/flags16/gm.png | Bin 0 -> 493 bytes base/resources.pk3dir/gfx/flags16/gn.png | Bin 0 -> 480 bytes base/resources.pk3dir/gfx/flags16/gp.png | Bin 0 -> 488 bytes base/resources.pk3dir/gfx/flags16/gq.png | Bin 0 -> 537 bytes base/resources.pk3dir/gfx/flags16/gr.png | Bin 0 -> 487 bytes base/resources.pk3dir/gfx/flags16/gs.png | Bin 0 -> 630 bytes base/resources.pk3dir/gfx/flags16/gt.png | Bin 0 -> 493 bytes base/resources.pk3dir/gfx/flags16/gu.png | Bin 0 -> 509 bytes base/resources.pk3dir/gfx/flags16/gw.png | Bin 0 -> 516 bytes base/resources.pk3dir/gfx/flags16/gy.png | Bin 0 -> 645 bytes base/resources.pk3dir/gfx/flags16/hk.png | Bin 0 -> 527 bytes base/resources.pk3dir/gfx/flags16/hm.png | Bin 0 -> 673 bytes base/resources.pk3dir/gfx/flags16/hn.png | Bin 0 -> 537 bytes base/resources.pk3dir/gfx/flags16/hr.png | Bin 0 -> 524 bytes base/resources.pk3dir/gfx/flags16/ht.png | Bin 0 -> 487 bytes base/resources.pk3dir/gfx/flags16/hu.png | Bin 0 -> 432 bytes base/resources.pk3dir/gfx/flags16/id.png | Bin 0 -> 430 bytes base/resources.pk3dir/gfx/flags16/ie.png | Bin 0 -> 481 bytes base/resources.pk3dir/gfx/flags16/il.png | Bin 0 -> 431 bytes base/resources.pk3dir/gfx/flags16/in.png | Bin 0 -> 503 bytes base/resources.pk3dir/gfx/flags16/io.png | Bin 0 -> 658 bytes base/resources.pk3dir/gfx/flags16/iq.png | Bin 0 -> 515 bytes base/resources.pk3dir/gfx/flags16/ir.png | Bin 0 -> 512 bytes base/resources.pk3dir/gfx/flags16/is.png | Bin 0 -> 532 bytes base/resources.pk3dir/gfx/flags16/it.png | Bin 0 -> 420 bytes base/resources.pk3dir/gfx/flags16/jm.png | Bin 0 -> 637 bytes base/resources.pk3dir/gfx/flags16/jo.png | Bin 0 -> 473 bytes base/resources.pk3dir/gfx/flags16/jp.png | Bin 0 -> 420 bytes base/resources.pk3dir/gfx/flags16/ke.png | Bin 0 -> 569 bytes base/resources.pk3dir/gfx/flags16/kg.png | Bin 0 -> 510 bytes base/resources.pk3dir/gfx/flags16/kh.png | Bin 0 -> 549 bytes base/resources.pk3dir/gfx/flags16/ki.png | Bin 0 -> 656 bytes base/resources.pk3dir/gfx/flags16/km.png | Bin 0 -> 577 bytes base/resources.pk3dir/gfx/flags16/kn.png | Bin 0 -> 604 bytes base/resources.pk3dir/gfx/flags16/kp.png | Bin 0 -> 561 bytes base/resources.pk3dir/gfx/flags16/kr.png | Bin 0 -> 592 bytes base/resources.pk3dir/gfx/flags16/kw.png | Bin 0 -> 486 bytes base/resources.pk3dir/gfx/flags16/ky.png | Bin 0 -> 643 bytes base/resources.pk3dir/gfx/flags16/kz.png | Bin 0 -> 616 bytes base/resources.pk3dir/gfx/flags16/la.png | Bin 0 -> 563 bytes base/resources.pk3dir/gfx/flags16/lb.png | Bin 0 -> 517 bytes base/resources.pk3dir/gfx/flags16/lc.png | Bin 0 -> 520 bytes base/resources.pk3dir/gfx/flags16/li.png | Bin 0 -> 537 bytes base/resources.pk3dir/gfx/flags16/lk.png | Bin 0 -> 627 bytes base/resources.pk3dir/gfx/flags16/lr.png | Bin 0 -> 466 bytes base/resources.pk3dir/gfx/flags16/ls.png | Bin 0 -> 628 bytes base/resources.pk3dir/gfx/flags16/lt.png | Bin 0 -> 508 bytes base/resources.pk3dir/gfx/flags16/lu.png | Bin 0 -> 481 bytes base/resources.pk3dir/gfx/flags16/lv.png | Bin 0 -> 465 bytes base/resources.pk3dir/gfx/flags16/ly.png | Bin 0 -> 419 bytes base/resources.pk3dir/gfx/flags16/ma.png | Bin 0 -> 432 bytes base/resources.pk3dir/gfx/flags16/mc.png | Bin 0 -> 380 bytes base/resources.pk3dir/gfx/flags16/md.png | Bin 0 -> 566 bytes base/resources.pk3dir/gfx/flags16/me.png | Bin 0 -> 448 bytes base/resources.pk3dir/gfx/flags16/mg.png | Bin 0 -> 453 bytes base/resources.pk3dir/gfx/flags16/mh.png | Bin 0 -> 628 bytes base/resources.pk3dir/gfx/flags16/mk.png | Bin 0 -> 664 bytes base/resources.pk3dir/gfx/flags16/ml.png | Bin 0 -> 474 bytes base/resources.pk3dir/gfx/flags16/mm.png | Bin 0 -> 483 bytes base/resources.pk3dir/gfx/flags16/mn.png | Bin 0 -> 492 bytes base/resources.pk3dir/gfx/flags16/mo.png | Bin 0 -> 588 bytes base/resources.pk3dir/gfx/flags16/mp.png | Bin 0 -> 597 bytes base/resources.pk3dir/gfx/flags16/mq.png | Bin 0 -> 655 bytes base/resources.pk3dir/gfx/flags16/mr.png | Bin 0 -> 569 bytes base/resources.pk3dir/gfx/flags16/ms.png | Bin 0 -> 614 bytes base/resources.pk3dir/gfx/flags16/mt.png | Bin 0 -> 420 bytes base/resources.pk3dir/gfx/flags16/mu.png | Bin 0 -> 496 bytes base/resources.pk3dir/gfx/flags16/mv.png | Bin 0 -> 542 bytes base/resources.pk3dir/gfx/flags16/mw.png | Bin 0 -> 529 bytes base/resources.pk3dir/gfx/flags16/mx.png | Bin 0 -> 574 bytes base/resources.pk3dir/gfx/flags16/my.png | Bin 0 -> 571 bytes base/resources.pk3dir/gfx/flags16/mz.png | Bin 0 -> 584 bytes base/resources.pk3dir/gfx/flags16/na.png | Bin 0 -> 647 bytes base/resources.pk3dir/gfx/flags16/nc.png | Bin 0 -> 591 bytes base/resources.pk3dir/gfx/flags16/ne.png | Bin 0 -> 537 bytes base/resources.pk3dir/gfx/flags16/nf.png | Bin 0 -> 602 bytes base/resources.pk3dir/gfx/flags16/ng.png | Bin 0 -> 482 bytes base/resources.pk3dir/gfx/flags16/ni.png | Bin 0 -> 508 bytes base/resources.pk3dir/gfx/flags16/nl.png | Bin 0 -> 453 bytes base/resources.pk3dir/gfx/flags16/no.png | Bin 0 -> 512 bytes base/resources.pk3dir/gfx/flags16/np.png | Bin 0 -> 443 bytes base/resources.pk3dir/gfx/flags16/nr.png | Bin 0 -> 527 bytes base/resources.pk3dir/gfx/flags16/nu.png | Bin 0 -> 572 bytes base/resources.pk3dir/gfx/flags16/nz.png | Bin 0 -> 639 bytes base/resources.pk3dir/gfx/flags16/om.png | Bin 0 -> 478 bytes base/resources.pk3dir/gfx/flags16/pa.png | Bin 0 -> 519 bytes base/resources.pk3dir/gfx/flags16/pe.png | Bin 0 -> 397 bytes base/resources.pk3dir/gfx/flags16/pf.png | Bin 0 -> 498 bytes base/resources.pk3dir/gfx/flags16/pg.png | Bin 0 -> 593 bytes base/resources.pk3dir/gfx/flags16/ph.png | Bin 0 -> 538 bytes base/resources.pk3dir/gfx/flags16/pk.png | Bin 0 -> 569 bytes base/resources.pk3dir/gfx/flags16/pl.png | Bin 0 -> 374 bytes base/resources.pk3dir/gfx/flags16/pm.png | Bin 0 -> 689 bytes base/resources.pk3dir/gfx/flags16/pn.png | Bin 0 -> 657 bytes base/resources.pk3dir/gfx/flags16/pr.png | Bin 0 -> 556 bytes base/resources.pk3dir/gfx/flags16/ps.png | Bin 0 -> 472 bytes base/resources.pk3dir/gfx/flags16/pt.png | Bin 0 -> 554 bytes base/resources.pk3dir/gfx/flags16/pw.png | Bin 0 -> 550 bytes base/resources.pk3dir/gfx/flags16/py.png | Bin 0 -> 473 bytes base/resources.pk3dir/gfx/flags16/qa.png | Bin 0 -> 450 bytes base/resources.pk3dir/gfx/flags16/re.png | Bin 0 -> 545 bytes base/resources.pk3dir/gfx/flags16/ro.png | Bin 0 -> 495 bytes base/resources.pk3dir/gfx/flags16/rs.png | Bin 0 -> 423 bytes base/resources.pk3dir/gfx/flags16/ru.png | Bin 0 -> 420 bytes base/resources.pk3dir/gfx/flags16/rw.png | Bin 0 -> 533 bytes base/resources.pk3dir/gfx/flags16/sa.png | Bin 0 -> 551 bytes base/resources.pk3dir/gfx/flags16/sb.png | Bin 0 -> 624 bytes base/resources.pk3dir/gfx/flags16/sc.png | Bin 0 -> 608 bytes .../resources.pk3dir/gfx/flags16/scotland.png | Bin 0 -> 649 bytes base/resources.pk3dir/gfx/flags16/sd.png | Bin 0 -> 492 bytes base/resources.pk3dir/gfx/flags16/se.png | Bin 0 -> 542 bytes base/resources.pk3dir/gfx/flags16/sg.png | Bin 0 -> 468 bytes base/resources.pk3dir/gfx/flags16/sh.png | Bin 0 -> 645 bytes base/resources.pk3dir/gfx/flags16/si.png | Bin 0 -> 510 bytes base/resources.pk3dir/gfx/flags16/sj.png | Bin 0 -> 512 bytes base/resources.pk3dir/gfx/flags16/sk.png | Bin 0 -> 562 bytes base/resources.pk3dir/gfx/flags16/sl.png | Bin 0 -> 436 bytes base/resources.pk3dir/gfx/flags16/sm.png | Bin 0 -> 502 bytes base/resources.pk3dir/gfx/flags16/sn.png | Bin 0 -> 532 bytes base/resources.pk3dir/gfx/flags16/so.png | Bin 0 -> 527 bytes base/resources.pk3dir/gfx/flags16/sr.png | Bin 0 -> 513 bytes base/resources.pk3dir/gfx/flags16/st.png | Bin 0 -> 584 bytes base/resources.pk3dir/gfx/flags16/sv.png | Bin 0 -> 501 bytes base/resources.pk3dir/gfx/flags16/sy.png | Bin 0 -> 422 bytes base/resources.pk3dir/gfx/flags16/sz.png | Bin 0 -> 643 bytes base/resources.pk3dir/gfx/flags16/tc.png | Bin 0 -> 624 bytes base/resources.pk3dir/gfx/flags16/td.png | Bin 0 -> 570 bytes base/resources.pk3dir/gfx/flags16/tf.png | Bin 0 -> 527 bytes base/resources.pk3dir/gfx/flags16/tg.png | Bin 0 -> 562 bytes base/resources.pk3dir/gfx/flags16/th.png | Bin 0 -> 452 bytes base/resources.pk3dir/gfx/flags16/tj.png | Bin 0 -> 496 bytes base/resources.pk3dir/gfx/flags16/tk.png | Bin 0 -> 638 bytes base/resources.pk3dir/gfx/flags16/tl.png | Bin 0 -> 514 bytes base/resources.pk3dir/gfx/flags16/tm.png | Bin 0 -> 593 bytes base/resources.pk3dir/gfx/flags16/tn.png | Bin 0 -> 495 bytes base/resources.pk3dir/gfx/flags16/to.png | Bin 0 -> 426 bytes base/resources.pk3dir/gfx/flags16/tr.png | Bin 0 -> 492 bytes base/resources.pk3dir/gfx/flags16/tt.png | Bin 0 -> 617 bytes base/resources.pk3dir/gfx/flags16/tv.png | Bin 0 -> 536 bytes base/resources.pk3dir/gfx/flags16/tw.png | Bin 0 -> 465 bytes base/resources.pk3dir/gfx/flags16/tz.png | Bin 0 -> 642 bytes base/resources.pk3dir/gfx/flags16/ua.png | Bin 0 -> 446 bytes base/resources.pk3dir/gfx/flags16/ug.png | Bin 0 -> 531 bytes base/resources.pk3dir/gfx/flags16/um.png | Bin 0 -> 571 bytes base/resources.pk3dir/gfx/flags16/us.png | Bin 0 -> 609 bytes base/resources.pk3dir/gfx/flags16/uy.png | Bin 0 -> 532 bytes base/resources.pk3dir/gfx/flags16/uz.png | Bin 0 -> 515 bytes base/resources.pk3dir/gfx/flags16/va.png | Bin 0 -> 553 bytes base/resources.pk3dir/gfx/flags16/vc.png | Bin 0 -> 577 bytes base/resources.pk3dir/gfx/flags16/ve.png | Bin 0 -> 528 bytes base/resources.pk3dir/gfx/flags16/vg.png | Bin 0 -> 630 bytes base/resources.pk3dir/gfx/flags16/vi.png | Bin 0 -> 616 bytes base/resources.pk3dir/gfx/flags16/vn.png | Bin 0 -> 474 bytes base/resources.pk3dir/gfx/flags16/vu.png | Bin 0 -> 604 bytes base/resources.pk3dir/gfx/flags16/wales.png | Bin 0 -> 652 bytes base/resources.pk3dir/gfx/flags16/wf.png | Bin 0 -> 554 bytes base/resources.pk3dir/gfx/flags16/ws.png | Bin 0 -> 476 bytes base/resources.pk3dir/gfx/flags16/ye.png | Bin 0 -> 413 bytes base/resources.pk3dir/gfx/flags16/yt.png | Bin 0 -> 593 bytes base/resources.pk3dir/gfx/flags16/za.png | Bin 0 -> 642 bytes base/resources.pk3dir/gfx/flags16/zm.png | Bin 0 -> 500 bytes base/resources.pk3dir/gfx/flags16/zw.png | Bin 0 -> 574 bytes base/resources.pk3dir/gfx/icon16/CREDITS | 3 + base/resources.pk3dir/gfx/icon16/accept.png | Bin 0 -> 781 bytes base/resources.pk3dir/gfx/icon16/add.png | Bin 0 -> 733 bytes base/resources.pk3dir/gfx/icon16/anchor.png | Bin 0 -> 523 bytes .../gfx/icon16/application.png | Bin 0 -> 464 bytes .../gfx/icon16/application_add.png | Bin 0 -> 619 bytes .../gfx/icon16/application_cascade.png | Bin 0 -> 524 bytes .../gfx/icon16/application_delete.png | Bin 0 -> 610 bytes .../gfx/icon16/application_double.png | Bin 0 -> 533 bytes .../gfx/icon16/application_edit.png | Bin 0 -> 703 bytes .../gfx/icon16/application_error.png | Bin 0 -> 656 bytes .../gfx/icon16/application_form.png | Bin 0 -> 467 bytes .../gfx/icon16/application_form_add.png | Bin 0 -> 592 bytes .../gfx/icon16/application_form_delete.png | Bin 0 -> 605 bytes .../gfx/icon16/application_form_edit.png | Bin 0 -> 714 bytes .../gfx/icon16/application_form_magnify.png | Bin 0 -> 612 bytes .../gfx/icon16/application_get.png | Bin 0 -> 581 bytes .../gfx/icon16/application_go.png | Bin 0 -> 634 bytes .../gfx/icon16/application_home.png | Bin 0 -> 685 bytes .../gfx/icon16/application_key.png | Bin 0 -> 670 bytes .../gfx/icon16/application_lightning.png | Bin 0 -> 656 bytes .../gfx/icon16/application_link.png | Bin 0 -> 701 bytes .../gfx/icon16/application_osx.png | Bin 0 -> 487 bytes .../gfx/icon16/application_osx_terminal.png | Bin 0 -> 525 bytes .../gfx/icon16/application_put.png | Bin 0 -> 585 bytes .../gfx/icon16/application_side_boxes.png | Bin 0 -> 478 bytes .../gfx/icon16/application_side_contract.png | Bin 0 -> 547 bytes .../gfx/icon16/application_side_expand.png | Bin 0 -> 581 bytes .../gfx/icon16/application_side_list.png | Bin 0 -> 510 bytes .../gfx/icon16/application_side_tree.png | Bin 0 -> 483 bytes .../gfx/icon16/application_split.png | Bin 0 -> 520 bytes .../icon16/application_tile_horizontal.png | Bin 0 -> 432 bytes .../gfx/icon16/application_tile_vertical.png | Bin 0 -> 492 bytes .../gfx/icon16/application_view_columns.png | Bin 0 -> 493 bytes .../gfx/icon16/application_view_detail.png | Bin 0 -> 576 bytes .../gfx/icon16/application_view_gallery.png | Bin 0 -> 555 bytes .../gfx/icon16/application_view_icons.png | Bin 0 -> 476 bytes .../gfx/icon16/application_view_list.png | Bin 0 -> 473 bytes .../gfx/icon16/application_view_tile.png | Bin 0 -> 465 bytes .../gfx/icon16/application_xp.png | Bin 0 -> 426 bytes .../gfx/icon16/application_xp_terminal.png | Bin 0 -> 507 bytes .../gfx/icon16/arrow_branch.png | Bin 0 -> 582 bytes .../gfx/icon16/arrow_divide.png | Bin 0 -> 677 bytes .../gfx/icon16/arrow_down.png | Bin 0 -> 379 bytes base/resources.pk3dir/gfx/icon16/arrow_in.png | Bin 0 -> 600 bytes .../gfx/icon16/arrow_inout.png | Bin 0 -> 551 bytes .../gfx/icon16/arrow_join.png | Bin 0 -> 626 bytes .../gfx/icon16/arrow_left.png | Bin 0 -> 345 bytes .../gfx/icon16/arrow_merge.png | Bin 0 -> 484 bytes .../resources.pk3dir/gfx/icon16/arrow_out.png | Bin 0 -> 594 bytes .../gfx/icon16/arrow_redo.png | Bin 0 -> 625 bytes .../gfx/icon16/arrow_refresh.png | Bin 0 -> 685 bytes .../gfx/icon16/arrow_refresh_small.png | Bin 0 -> 506 bytes .../gfx/icon16/arrow_right.png | Bin 0 -> 349 bytes .../gfx/icon16/arrow_rotate_anticlockwise.png | Bin 0 -> 608 bytes .../gfx/icon16/arrow_rotate_clockwise.png | Bin 0 -> 602 bytes .../gfx/icon16/arrow_switch.png | Bin 0 -> 683 bytes .../gfx/icon16/arrow_turn_left.png | Bin 0 -> 516 bytes .../gfx/icon16/arrow_turn_right.png | Bin 0 -> 489 bytes .../gfx/icon16/arrow_undo.png | Bin 0 -> 631 bytes base/resources.pk3dir/gfx/icon16/arrow_up.png | Bin 0 -> 372 bytes .../gfx/icon16/asterisk_orange.png | Bin 0 -> 760 bytes .../gfx/icon16/asterisk_yellow.png | Bin 0 -> 743 bytes base/resources.pk3dir/gfx/icon16/attach.png | Bin 0 -> 391 bytes .../gfx/icon16/award_star_add.png | Bin 0 -> 853 bytes .../gfx/icon16/award_star_bronze_1.png | Bin 0 -> 733 bytes .../gfx/icon16/award_star_bronze_2.png | Bin 0 -> 755 bytes .../gfx/icon16/award_star_bronze_3.png | Bin 0 -> 754 bytes .../gfx/icon16/award_star_delete.png | Bin 0 -> 849 bytes .../gfx/icon16/award_star_gold_1.png | Bin 0 -> 753 bytes .../gfx/icon16/award_star_gold_2.png | Bin 0 -> 770 bytes .../gfx/icon16/award_star_gold_3.png | Bin 0 -> 781 bytes .../gfx/icon16/award_star_silver_1.png | Bin 0 -> 714 bytes .../gfx/icon16/award_star_silver_2.png | Bin 0 -> 734 bytes .../gfx/icon16/award_star_silver_3.png | Bin 0 -> 738 bytes base/resources.pk3dir/gfx/icon16/basket.png | Bin 0 -> 669 bytes .../gfx/icon16/basket_add.png | Bin 0 -> 752 bytes .../gfx/icon16/basket_delete.png | Bin 0 -> 773 bytes .../gfx/icon16/basket_edit.png | Bin 0 -> 811 bytes .../gfx/icon16/basket_error.png | Bin 0 -> 794 bytes .../resources.pk3dir/gfx/icon16/basket_go.png | Bin 0 -> 777 bytes .../gfx/icon16/basket_put.png | Bin 0 -> 733 bytes .../gfx/icon16/basket_remove.png | Bin 0 -> 738 bytes base/resources.pk3dir/gfx/icon16/bell.png | Bin 0 -> 789 bytes base/resources.pk3dir/gfx/icon16/bell_add.png | Bin 0 -> 816 bytes .../gfx/icon16/bell_delete.png | Bin 0 -> 824 bytes .../gfx/icon16/bell_error.png | Bin 0 -> 813 bytes base/resources.pk3dir/gfx/icon16/bell_go.png | Bin 0 -> 836 bytes .../resources.pk3dir/gfx/icon16/bell_link.png | Bin 0 -> 850 bytes base/resources.pk3dir/gfx/icon16/bin.png | Bin 0 -> 476 bytes .../gfx/icon16/bin_closed.png | Bin 0 -> 363 bytes .../resources.pk3dir/gfx/icon16/bin_empty.png | Bin 0 -> 475 bytes base/resources.pk3dir/gfx/icon16/bomb.png | Bin 0 -> 793 bytes base/resources.pk3dir/gfx/icon16/book.png | Bin 0 -> 593 bytes base/resources.pk3dir/gfx/icon16/book_add.png | Bin 0 -> 714 bytes .../gfx/icon16/book_addresses.png | Bin 0 -> 770 bytes .../gfx/icon16/book_delete.png | Bin 0 -> 719 bytes .../resources.pk3dir/gfx/icon16/book_edit.png | Bin 0 -> 813 bytes .../gfx/icon16/book_error.png | Bin 0 -> 734 bytes base/resources.pk3dir/gfx/icon16/book_go.png | Bin 0 -> 745 bytes base/resources.pk3dir/gfx/icon16/book_key.png | Bin 0 -> 779 bytes .../resources.pk3dir/gfx/icon16/book_link.png | Bin 0 -> 789 bytes .../resources.pk3dir/gfx/icon16/book_next.png | Bin 0 -> 702 bytes .../resources.pk3dir/gfx/icon16/book_open.png | Bin 0 -> 622 bytes .../gfx/icon16/book_previous.png | Bin 0 -> 680 bytes base/resources.pk3dir/gfx/icon16/box.png | Bin 0 -> 555 bytes base/resources.pk3dir/gfx/icon16/brick.png | Bin 0 -> 452 bytes .../resources.pk3dir/gfx/icon16/brick_add.png | Bin 0 -> 729 bytes .../gfx/icon16/brick_delete.png | Bin 0 -> 745 bytes .../gfx/icon16/brick_edit.png | Bin 0 -> 775 bytes .../gfx/icon16/brick_error.png | Bin 0 -> 798 bytes base/resources.pk3dir/gfx/icon16/brick_go.png | Bin 0 -> 790 bytes .../gfx/icon16/brick_link.png | Bin 0 -> 764 bytes base/resources.pk3dir/gfx/icon16/bricks.png | Bin 0 -> 825 bytes .../resources.pk3dir/gfx/icon16/briefcase.png | Bin 0 -> 793 bytes base/resources.pk3dir/gfx/icon16/bug.png | Bin 0 -> 774 bytes base/resources.pk3dir/gfx/icon16/bug_add.png | Bin 0 -> 806 bytes .../gfx/icon16/bug_delete.png | Bin 0 -> 836 bytes base/resources.pk3dir/gfx/icon16/bug_edit.png | Bin 0 -> 873 bytes .../resources.pk3dir/gfx/icon16/bug_error.png | Bin 0 -> 841 bytes base/resources.pk3dir/gfx/icon16/bug_go.png | Bin 0 -> 831 bytes base/resources.pk3dir/gfx/icon16/bug_link.png | Bin 0 -> 847 bytes base/resources.pk3dir/gfx/icon16/building.png | Bin 0 -> 556 bytes .../gfx/icon16/building_add.png | Bin 0 -> 631 bytes .../gfx/icon16/building_delete.png | Bin 0 -> 633 bytes .../gfx/icon16/building_edit.png | Bin 0 -> 731 bytes .../gfx/icon16/building_error.png | Bin 0 -> 653 bytes .../gfx/icon16/building_go.png | Bin 0 -> 665 bytes .../gfx/icon16/building_key.png | Bin 0 -> 705 bytes .../gfx/icon16/building_link.png | Bin 0 -> 668 bytes .../gfx/icon16/bullet_add.png | Bin 0 -> 286 bytes .../gfx/icon16/bullet_arrow_bottom.png | Bin 0 -> 229 bytes .../gfx/icon16/bullet_arrow_down.png | Bin 0 -> 201 bytes .../gfx/icon16/bullet_arrow_top.png | Bin 0 -> 230 bytes .../gfx/icon16/bullet_arrow_up.png | Bin 0 -> 201 bytes .../gfx/icon16/bullet_black.png | Bin 0 -> 211 bytes .../gfx/icon16/bullet_blue.png | Bin 0 -> 289 bytes .../gfx/icon16/bullet_delete.png | Bin 0 -> 308 bytes .../gfx/icon16/bullet_disk.png | Bin 0 -> 483 bytes .../gfx/icon16/bullet_error.png | Bin 0 -> 454 bytes .../gfx/icon16/bullet_feed.png | Bin 0 -> 262 bytes .../resources.pk3dir/gfx/icon16/bullet_go.png | Bin 0 -> 410 bytes .../gfx/icon16/bullet_green.png | Bin 0 -> 295 bytes .../gfx/icon16/bullet_key.png | Bin 0 -> 436 bytes .../gfx/icon16/bullet_orange.png | Bin 0 -> 283 bytes .../gfx/icon16/bullet_picture.png | Bin 0 -> 470 bytes .../gfx/icon16/bullet_pink.png | Bin 0 -> 286 bytes .../gfx/icon16/bullet_purple.png | Bin 0 -> 294 bytes .../gfx/icon16/bullet_red.png | Bin 0 -> 287 bytes .../gfx/icon16/bullet_star.png | Bin 0 -> 331 bytes .../gfx/icon16/bullet_toggle_minus.png | Bin 0 -> 207 bytes .../gfx/icon16/bullet_toggle_plus.png | Bin 0 -> 209 bytes .../gfx/icon16/bullet_white.png | Bin 0 -> 201 bytes .../gfx/icon16/bullet_wrench.png | Bin 0 -> 448 bytes .../gfx/icon16/bullet_yellow.png | Bin 0 -> 287 bytes base/resources.pk3dir/gfx/icon16/cake.png | Bin 0 -> 676 bytes .../gfx/icon16/calculator.png | Bin 0 -> 543 bytes .../gfx/icon16/calculator_add.png | Bin 0 -> 660 bytes .../gfx/icon16/calculator_delete.png | Bin 0 -> 692 bytes .../gfx/icon16/calculator_edit.png | Bin 0 -> 767 bytes .../gfx/icon16/calculator_error.png | Bin 0 -> 731 bytes .../gfx/icon16/calculator_link.png | Bin 0 -> 723 bytes base/resources.pk3dir/gfx/icon16/calendar.png | Bin 0 -> 675 bytes .../gfx/icon16/calendar_add.png | Bin 0 -> 723 bytes .../gfx/icon16/calendar_delete.png | Bin 0 -> 742 bytes .../gfx/icon16/calendar_edit.png | Bin 0 -> 777 bytes .../gfx/icon16/calendar_link.png | Bin 0 -> 795 bytes .../gfx/icon16/calendar_view_day.png | Bin 0 -> 572 bytes .../gfx/icon16/calendar_view_month.png | Bin 0 -> 595 bytes .../gfx/icon16/calendar_view_week.png | Bin 0 -> 480 bytes base/resources.pk3dir/gfx/icon16/camera.png | Bin 0 -> 665 bytes .../gfx/icon16/camera_add.png | Bin 0 -> 800 bytes .../gfx/icon16/camera_delete.png | Bin 0 -> 797 bytes .../gfx/icon16/camera_edit.png | Bin 0 -> 872 bytes .../gfx/icon16/camera_error.png | Bin 0 -> 835 bytes .../resources.pk3dir/gfx/icon16/camera_go.png | Bin 0 -> 809 bytes .../gfx/icon16/camera_link.png | Bin 0 -> 839 bytes .../gfx/icon16/camera_small.png | Bin 0 -> 489 bytes base/resources.pk3dir/gfx/icon16/cancel.png | Bin 0 -> 587 bytes base/resources.pk3dir/gfx/icon16/car.png | Bin 0 -> 610 bytes base/resources.pk3dir/gfx/icon16/car_add.png | Bin 0 -> 677 bytes .../gfx/icon16/car_delete.png | Bin 0 -> 689 bytes base/resources.pk3dir/gfx/icon16/cart.png | Bin 0 -> 421 bytes base/resources.pk3dir/gfx/icon16/cart_add.png | Bin 0 -> 711 bytes .../gfx/icon16/cart_delete.png | Bin 0 -> 742 bytes .../resources.pk3dir/gfx/icon16/cart_edit.png | Bin 0 -> 789 bytes .../gfx/icon16/cart_error.png | Bin 0 -> 790 bytes base/resources.pk3dir/gfx/icon16/cart_go.png | Bin 0 -> 763 bytes base/resources.pk3dir/gfx/icon16/cart_put.png | Bin 0 -> 763 bytes .../gfx/icon16/cart_remove.png | Bin 0 -> 769 bytes base/resources.pk3dir/gfx/icon16/cd.png | Bin 0 -> 673 bytes base/resources.pk3dir/gfx/icon16/cd_add.png | Bin 0 -> 758 bytes base/resources.pk3dir/gfx/icon16/cd_burn.png | Bin 0 -> 756 bytes .../resources.pk3dir/gfx/icon16/cd_delete.png | Bin 0 -> 767 bytes base/resources.pk3dir/gfx/icon16/cd_edit.png | Bin 0 -> 790 bytes base/resources.pk3dir/gfx/icon16/cd_eject.png | Bin 0 -> 786 bytes base/resources.pk3dir/gfx/icon16/cd_go.png | Bin 0 -> 793 bytes .../resources.pk3dir/gfx/icon16/chart_bar.png | Bin 0 -> 541 bytes .../gfx/icon16/chart_bar_add.png | Bin 0 -> 626 bytes .../gfx/icon16/chart_bar_delete.png | Bin 0 -> 636 bytes .../gfx/icon16/chart_bar_edit.png | Bin 0 -> 754 bytes .../gfx/icon16/chart_bar_error.png | Bin 0 -> 671 bytes .../gfx/icon16/chart_bar_link.png | Bin 0 -> 712 bytes .../gfx/icon16/chart_curve.png | Bin 0 -> 710 bytes .../gfx/icon16/chart_curve_add.png | Bin 0 -> 761 bytes .../gfx/icon16/chart_curve_delete.png | Bin 0 -> 782 bytes .../gfx/icon16/chart_curve_edit.png | Bin 0 -> 822 bytes .../gfx/icon16/chart_curve_error.png | Bin 0 -> 837 bytes .../gfx/icon16/chart_curve_go.png | Bin 0 -> 823 bytes .../gfx/icon16/chart_curve_link.png | Bin 0 -> 829 bytes .../gfx/icon16/chart_line.png | Bin 0 -> 526 bytes .../gfx/icon16/chart_line_add.png | Bin 0 -> 655 bytes .../gfx/icon16/chart_line_delete.png | Bin 0 -> 675 bytes .../gfx/icon16/chart_line_edit.png | Bin 0 -> 718 bytes .../gfx/icon16/chart_line_error.png | Bin 0 -> 741 bytes .../gfx/icon16/chart_line_link.png | Bin 0 -> 749 bytes .../gfx/icon16/chart_organisation.png | Bin 0 -> 444 bytes .../gfx/icon16/chart_organisation_add.png | Bin 0 -> 551 bytes .../gfx/icon16/chart_organisation_delete.png | Bin 0 -> 563 bytes .../resources.pk3dir/gfx/icon16/chart_pie.png | Bin 0 -> 918 bytes .../gfx/icon16/chart_pie_add.png | Bin 0 -> 975 bytes .../gfx/icon16/chart_pie_delete.png | Bin 0 -> 983 bytes .../gfx/icon16/chart_pie_edit.png | Bin 0 -> 986 bytes .../gfx/icon16/chart_pie_error.png | Bin 0 -> 989 bytes .../gfx/icon16/chart_pie_link.png | Bin 0 -> 1021 bytes base/resources.pk3dir/gfx/icon16/clock.png | Bin 0 -> 882 bytes .../resources.pk3dir/gfx/icon16/clock_add.png | Bin 0 -> 925 bytes .../gfx/icon16/clock_delete.png | Bin 0 -> 952 bytes .../gfx/icon16/clock_edit.png | Bin 0 -> 967 bytes .../gfx/icon16/clock_error.png | Bin 0 -> 953 bytes base/resources.pk3dir/gfx/icon16/clock_go.png | Bin 0 -> 959 bytes .../gfx/icon16/clock_link.png | Bin 0 -> 961 bytes .../gfx/icon16/clock_pause.png | Bin 0 -> 927 bytes .../gfx/icon16/clock_play.png | Bin 0 -> 943 bytes .../resources.pk3dir/gfx/icon16/clock_red.png | Bin 0 -> 889 bytes .../gfx/icon16/clock_stop.png | Bin 0 -> 922 bytes base/resources.pk3dir/gfx/icon16/cog.png | Bin 0 -> 512 bytes base/resources.pk3dir/gfx/icon16/cog_add.png | Bin 0 -> 814 bytes .../gfx/icon16/cog_delete.png | Bin 0 -> 847 bytes base/resources.pk3dir/gfx/icon16/cog_edit.png | Bin 0 -> 865 bytes .../resources.pk3dir/gfx/icon16/cog_error.png | Bin 0 -> 869 bytes base/resources.pk3dir/gfx/icon16/cog_go.png | Bin 0 -> 859 bytes base/resources.pk3dir/gfx/icon16/coins.png | Bin 0 -> 732 bytes .../resources.pk3dir/gfx/icon16/coins_add.png | Bin 0 -> 789 bytes .../gfx/icon16/coins_delete.png | Bin 0 -> 775 bytes .../gfx/icon16/color_swatch.png | Bin 0 -> 209 bytes .../gfx/icon16/color_wheel.png | Bin 0 -> 892 bytes base/resources.pk3dir/gfx/icon16/comment.png | Bin 0 -> 413 bytes .../gfx/icon16/comment_add.png | Bin 0 -> 530 bytes .../gfx/icon16/comment_delete.png | Bin 0 -> 548 bytes .../gfx/icon16/comment_edit.png | Bin 0 -> 644 bytes base/resources.pk3dir/gfx/icon16/comments.png | Bin 0 -> 557 bytes .../gfx/icon16/comments_add.png | Bin 0 -> 648 bytes .../gfx/icon16/comments_delete.png | Bin 0 -> 670 bytes base/resources.pk3dir/gfx/icon16/compress.png | Bin 0 -> 766 bytes base/resources.pk3dir/gfx/icon16/computer.png | Bin 0 -> 667 bytes .../gfx/icon16/computer_add.png | Bin 0 -> 781 bytes .../gfx/icon16/computer_delete.png | Bin 0 -> 775 bytes .../gfx/icon16/computer_edit.png | Bin 0 -> 792 bytes .../gfx/icon16/computer_error.png | Bin 0 -> 784 bytes .../gfx/icon16/computer_go.png | Bin 0 -> 777 bytes .../gfx/icon16/computer_key.png | Bin 0 -> 771 bytes .../gfx/icon16/computer_link.png | Bin 0 -> 792 bytes base/resources.pk3dir/gfx/icon16/connect.png | Bin 0 -> 748 bytes base/resources.pk3dir/gfx/icon16/contrast.png | Bin 0 -> 434 bytes .../gfx/icon16/contrast_decrease.png | Bin 0 -> 695 bytes .../gfx/icon16/contrast_high.png | Bin 0 -> 435 bytes .../gfx/icon16/contrast_increase.png | Bin 0 -> 717 bytes .../gfx/icon16/contrast_low.png | Bin 0 -> 421 bytes .../gfx/icon16/control_eject.png | Bin 0 -> 603 bytes .../gfx/icon16/control_eject_blue.png | Bin 0 -> 727 bytes .../gfx/icon16/control_end.png | Bin 0 -> 621 bytes .../gfx/icon16/control_end_blue.png | Bin 0 -> 737 bytes .../gfx/icon16/control_equalizer.png | Bin 0 -> 432 bytes .../gfx/icon16/control_equalizer_blue.png | Bin 0 -> 764 bytes .../gfx/icon16/control_fastforward.png | Bin 0 -> 607 bytes .../gfx/icon16/control_fastforward_blue.png | Bin 0 -> 736 bytes .../gfx/icon16/control_pause.png | Bin 0 -> 598 bytes .../gfx/icon16/control_pause_blue.png | Bin 0 -> 721 bytes .../gfx/icon16/control_play.png | Bin 0 -> 592 bytes .../gfx/icon16/control_play_blue.png | Bin 0 -> 717 bytes .../gfx/icon16/control_repeat.png | Bin 0 -> 422 bytes .../gfx/icon16/control_repeat_blue.png | Bin 0 -> 750 bytes .../gfx/icon16/control_rewind.png | Bin 0 -> 614 bytes .../gfx/icon16/control_rewind_blue.png | Bin 0 -> 745 bytes .../gfx/icon16/control_start.png | Bin 0 -> 604 bytes .../gfx/icon16/control_start_blue.png | Bin 0 -> 720 bytes .../gfx/icon16/control_stop.png | Bin 0 -> 403 bytes .../gfx/icon16/control_stop_blue.png | Bin 0 -> 695 bytes .../gfx/icon16/controller.png | Bin 0 -> 666 bytes .../gfx/icon16/controller_add.png | Bin 0 -> 759 bytes .../gfx/icon16/controller_delete.png | Bin 0 -> 770 bytes .../gfx/icon16/controller_error.png | Bin 0 -> 815 bytes .../gfx/icon16/creditcards.png | Bin 0 -> 693 bytes base/resources.pk3dir/gfx/icon16/cross.png | Bin 0 -> 655 bytes .../gfx/icon16/cross_mono.png | Bin 0 -> 4707 bytes base/resources.pk3dir/gfx/icon16/css.png | Bin 0 -> 524 bytes base/resources.pk3dir/gfx/icon16/css_add.png | Bin 0 -> 666 bytes .../gfx/icon16/css_delete.png | Bin 0 -> 654 bytes base/resources.pk3dir/gfx/icon16/css_go.png | Bin 0 -> 655 bytes .../resources.pk3dir/gfx/icon16/css_valid.png | Bin 0 -> 661 bytes base/resources.pk3dir/gfx/icon16/cup.png | Bin 0 -> 633 bytes base/resources.pk3dir/gfx/icon16/cup_add.png | Bin 0 -> 715 bytes .../gfx/icon16/cup_delete.png | Bin 0 -> 731 bytes base/resources.pk3dir/gfx/icon16/cup_edit.png | Bin 0 -> 778 bytes .../resources.pk3dir/gfx/icon16/cup_error.png | Bin 0 -> 790 bytes base/resources.pk3dir/gfx/icon16/cup_go.png | Bin 0 -> 780 bytes base/resources.pk3dir/gfx/icon16/cup_key.png | Bin 0 -> 776 bytes base/resources.pk3dir/gfx/icon16/cup_link.png | Bin 0 -> 760 bytes base/resources.pk3dir/gfx/icon16/cursor.png | Bin 0 -> 354 bytes base/resources.pk3dir/gfx/icon16/cut.png | Bin 0 -> 648 bytes base/resources.pk3dir/gfx/icon16/cut_red.png | Bin 0 -> 650 bytes base/resources.pk3dir/gfx/icon16/database.png | Bin 0 -> 390 bytes .../gfx/icon16/database_add.png | Bin 0 -> 658 bytes .../gfx/icon16/database_connect.png | Bin 0 -> 763 bytes .../gfx/icon16/database_delete.png | Bin 0 -> 659 bytes .../gfx/icon16/database_edit.png | Bin 0 -> 767 bytes .../gfx/icon16/database_error.png | Bin 0 -> 682 bytes .../gfx/icon16/database_gear.png | Bin 0 -> 468 bytes .../gfx/icon16/database_go.png | Bin 0 -> 698 bytes .../gfx/icon16/database_key.png | Bin 0 -> 764 bytes .../gfx/icon16/database_lightning.png | Bin 0 -> 775 bytes .../gfx/icon16/database_link.png | Bin 0 -> 679 bytes .../gfx/icon16/database_refresh.png | Bin 0 -> 770 bytes .../gfx/icon16/database_save.png | Bin 0 -> 755 bytes .../gfx/icon16/database_table.png | Bin 0 -> 726 bytes base/resources.pk3dir/gfx/icon16/date.png | Bin 0 -> 626 bytes base/resources.pk3dir/gfx/icon16/date_add.png | Bin 0 -> 703 bytes .../gfx/icon16/date_delete.png | Bin 0 -> 716 bytes .../resources.pk3dir/gfx/icon16/date_edit.png | Bin 0 -> 799 bytes .../gfx/icon16/date_error.png | Bin 0 -> 753 bytes base/resources.pk3dir/gfx/icon16/date_go.png | Bin 0 -> 753 bytes .../resources.pk3dir/gfx/icon16/date_link.png | Bin 0 -> 764 bytes .../gfx/icon16/date_magnify.png | Bin 0 -> 711 bytes .../resources.pk3dir/gfx/icon16/date_next.png | Bin 0 -> 688 bytes .../gfx/icon16/date_previous.png | Bin 0 -> 720 bytes base/resources.pk3dir/gfx/icon16/delete.png | Bin 0 -> 715 bytes .../gfx/icon16/disconnect.png | Bin 0 -> 796 bytes base/resources.pk3dir/gfx/icon16/disk.png | Bin 0 -> 620 bytes .../gfx/icon16/disk_multiple.png | Bin 0 -> 691 bytes base/resources.pk3dir/gfx/icon16/door.png | Bin 0 -> 412 bytes base/resources.pk3dir/gfx/icon16/door_in.png | Bin 0 -> 693 bytes .../resources.pk3dir/gfx/icon16/door_open.png | Bin 0 -> 508 bytes base/resources.pk3dir/gfx/icon16/door_out.png | Bin 0 -> 688 bytes base/resources.pk3dir/gfx/icon16/drink.png | Bin 0 -> 692 bytes .../gfx/icon16/drink_empty.png | Bin 0 -> 433 bytes base/resources.pk3dir/gfx/icon16/drive.png | Bin 0 -> 346 bytes .../resources.pk3dir/gfx/icon16/drive_add.png | Bin 0 -> 623 bytes .../gfx/icon16/drive_burn.png | Bin 0 -> 608 bytes base/resources.pk3dir/gfx/icon16/drive_cd.png | Bin 0 -> 734 bytes .../gfx/icon16/drive_cd_empty.png | Bin 0 -> 341 bytes .../gfx/icon16/drive_delete.png | Bin 0 -> 628 bytes .../gfx/icon16/drive_disk.png | Bin 0 -> 695 bytes .../gfx/icon16/drive_edit.png | Bin 0 -> 714 bytes .../gfx/icon16/drive_error.png | Bin 0 -> 705 bytes base/resources.pk3dir/gfx/icon16/drive_go.png | Bin 0 -> 661 bytes .../resources.pk3dir/gfx/icon16/drive_key.png | Bin 0 -> 681 bytes .../gfx/icon16/drive_link.png | Bin 0 -> 679 bytes .../gfx/icon16/drive_magnify.png | Bin 0 -> 641 bytes .../gfx/icon16/drive_network.png | Bin 0 -> 585 bytes .../gfx/icon16/drive_rename.png | Bin 0 -> 494 bytes .../gfx/icon16/drive_user.png | Bin 0 -> 712 bytes .../resources.pk3dir/gfx/icon16/drive_web.png | Bin 0 -> 686 bytes base/resources.pk3dir/gfx/icon16/dvd.png | Bin 0 -> 764 bytes base/resources.pk3dir/gfx/icon16/dvd_add.png | Bin 0 -> 788 bytes .../gfx/icon16/dvd_delete.png | Bin 0 -> 800 bytes base/resources.pk3dir/gfx/icon16/dvd_edit.png | Bin 0 -> 844 bytes .../resources.pk3dir/gfx/icon16/dvd_error.png | Bin 0 -> 854 bytes base/resources.pk3dir/gfx/icon16/dvd_go.png | Bin 0 -> 854 bytes base/resources.pk3dir/gfx/icon16/dvd_key.png | Bin 0 -> 816 bytes base/resources.pk3dir/gfx/icon16/dvd_link.png | Bin 0 -> 819 bytes base/resources.pk3dir/gfx/icon16/email.png | Bin 0 -> 641 bytes .../resources.pk3dir/gfx/icon16/email_add.png | Bin 0 -> 761 bytes .../gfx/icon16/email_attach.png | Bin 0 -> 793 bytes .../gfx/icon16/email_delete.png | Bin 0 -> 756 bytes .../gfx/icon16/email_edit.png | Bin 0 -> 756 bytes .../gfx/icon16/email_error.png | Bin 0 -> 792 bytes base/resources.pk3dir/gfx/icon16/email_go.png | Bin 0 -> 754 bytes .../gfx/icon16/email_link.png | Bin 0 -> 821 bytes .../gfx/icon16/email_open.png | Bin 0 -> 783 bytes .../gfx/icon16/email_open_image.png | Bin 0 -> 811 bytes .../gfx/icon16/emoticon_evilgrin.png | Bin 0 -> 727 bytes .../gfx/icon16/emoticon_grin.png | Bin 0 -> 714 bytes .../gfx/icon16/emoticon_happy.png | Bin 0 -> 731 bytes .../gfx/icon16/emoticon_smile.png | Bin 0 -> 725 bytes .../gfx/icon16/emoticon_surprised.png | Bin 0 -> 741 bytes .../gfx/icon16/emoticon_tongue.png | Bin 0 -> 727 bytes .../gfx/icon16/emoticon_unhappy.png | Bin 0 -> 723 bytes .../gfx/icon16/emoticon_waii.png | Bin 0 -> 737 bytes .../gfx/icon16/emoticon_wink.png | Bin 0 -> 712 bytes base/resources.pk3dir/gfx/icon16/error.png | Bin 0 -> 666 bytes .../resources.pk3dir/gfx/icon16/error_add.png | Bin 0 -> 710 bytes .../gfx/icon16/error_delete.png | Bin 0 -> 729 bytes base/resources.pk3dir/gfx/icon16/error_go.png | Bin 0 -> 734 bytes .../gfx/icon16/exclamation.png | Bin 0 -> 701 bytes base/resources.pk3dir/gfx/icon16/eye.png | Bin 0 -> 750 bytes base/resources.pk3dir/gfx/icon16/feed.png | Bin 0 -> 691 bytes base/resources.pk3dir/gfx/icon16/feed_add.png | Bin 0 -> 763 bytes .../gfx/icon16/feed_delete.png | Bin 0 -> 746 bytes .../resources.pk3dir/gfx/icon16/feed_disk.png | Bin 0 -> 738 bytes .../resources.pk3dir/gfx/icon16/feed_edit.png | Bin 0 -> 801 bytes .../gfx/icon16/feed_error.png | Bin 0 -> 770 bytes base/resources.pk3dir/gfx/icon16/feed_go.png | Bin 0 -> 761 bytes base/resources.pk3dir/gfx/icon16/feed_key.png | Bin 0 -> 771 bytes .../resources.pk3dir/gfx/icon16/feed_link.png | Bin 0 -> 806 bytes .../gfx/icon16/feed_magnify.png | Bin 0 -> 737 bytes base/resources.pk3dir/gfx/icon16/female.png | Bin 0 -> 590 bytes base/resources.pk3dir/gfx/icon16/film.png | Bin 0 -> 653 bytes base/resources.pk3dir/gfx/icon16/film_add.png | Bin 0 -> 739 bytes .../gfx/icon16/film_delete.png | Bin 0 -> 730 bytes .../resources.pk3dir/gfx/icon16/film_edit.png | Bin 0 -> 855 bytes .../gfx/icon16/film_error.png | Bin 0 -> 800 bytes base/resources.pk3dir/gfx/icon16/film_go.png | Bin 0 -> 813 bytes base/resources.pk3dir/gfx/icon16/film_key.png | Bin 0 -> 835 bytes .../resources.pk3dir/gfx/icon16/film_link.png | Bin 0 -> 830 bytes .../resources.pk3dir/gfx/icon16/film_save.png | Bin 0 -> 806 bytes base/resources.pk3dir/gfx/icon16/find.png | Bin 0 -> 659 bytes .../resources.pk3dir/gfx/icon16/flag_blue.png | Bin 0 -> 671 bytes .../gfx/icon16/flag_green.png | Bin 0 -> 672 bytes .../gfx/icon16/flag_orange.png | Bin 0 -> 669 bytes .../resources.pk3dir/gfx/icon16/flag_pink.png | Bin 0 -> 651 bytes .../gfx/icon16/flag_purple.png | Bin 0 -> 656 bytes base/resources.pk3dir/gfx/icon16/flag_red.png | Bin 0 -> 665 bytes .../gfx/icon16/flag_yellow.png | Bin 0 -> 671 bytes base/resources.pk3dir/gfx/icon16/folder.png | Bin 0 -> 537 bytes .../gfx/icon16/folder_add.png | Bin 0 -> 668 bytes .../gfx/icon16/folder_bell.png | Bin 0 -> 781 bytes .../gfx/icon16/folder_brick.png | Bin 0 -> 735 bytes .../gfx/icon16/folder_bug.png | Bin 0 -> 829 bytes .../gfx/icon16/folder_camera.png | Bin 0 -> 729 bytes .../gfx/icon16/folder_database.png | Bin 0 -> 687 bytes .../gfx/icon16/folder_delete.png | Bin 0 -> 666 bytes .../gfx/icon16/folder_edit.png | Bin 0 -> 733 bytes .../gfx/icon16/folder_error.png | Bin 0 -> 727 bytes .../gfx/icon16/folder_explore.png | Bin 0 -> 679 bytes .../gfx/icon16/folder_feed.png | Bin 0 -> 691 bytes .../gfx/icon16/folder_find.png | Bin 0 -> 795 bytes .../resources.pk3dir/gfx/icon16/folder_go.png | Bin 0 -> 694 bytes .../gfx/icon16/folder_heart.png | Bin 0 -> 741 bytes .../gfx/icon16/folder_image.png | Bin 0 -> 677 bytes .../gfx/icon16/folder_key.png | Bin 0 -> 720 bytes .../gfx/icon16/folder_lightbulb.png | Bin 0 -> 741 bytes .../gfx/icon16/folder_link.png | Bin 0 -> 785 bytes .../gfx/icon16/folder_magnify.png | Bin 0 -> 686 bytes .../gfx/icon16/folder_page.png | Bin 0 -> 688 bytes .../gfx/icon16/folder_page_white.png | Bin 0 -> 639 bytes .../gfx/icon16/folder_palette.png | Bin 0 -> 822 bytes .../gfx/icon16/folder_picture.png | Bin 0 -> 713 bytes .../gfx/icon16/folder_star.png | Bin 0 -> 755 bytes .../gfx/icon16/folder_table.png | Bin 0 -> 675 bytes .../gfx/icon16/folder_user.png | Bin 0 -> 730 bytes .../gfx/icon16/folder_wrench.png | Bin 0 -> 740 bytes base/resources.pk3dir/gfx/icon16/font.png | Bin 0 -> 567 bytes base/resources.pk3dir/gfx/icon16/font_add.png | Bin 0 -> 634 bytes .../gfx/icon16/font_delete.png | Bin 0 -> 661 bytes base/resources.pk3dir/gfx/icon16/font_go.png | Bin 0 -> 700 bytes base/resources.pk3dir/gfx/icon16/group.png | Bin 0 -> 753 bytes .../resources.pk3dir/gfx/icon16/group_add.png | Bin 0 -> 807 bytes .../gfx/icon16/group_delete.png | Bin 0 -> 827 bytes .../gfx/icon16/group_edit.png | Bin 0 -> 785 bytes .../gfx/icon16/group_error.png | Bin 0 -> 842 bytes .../gfx/icon16/group_gear.png | Bin 0 -> 824 bytes base/resources.pk3dir/gfx/icon16/group_go.png | Bin 0 -> 842 bytes .../resources.pk3dir/gfx/icon16/group_key.png | Bin 0 -> 813 bytes .../gfx/icon16/group_link.png | Bin 0 -> 858 bytes base/resources.pk3dir/gfx/icon16/heart.png | Bin 0 -> 749 bytes .../resources.pk3dir/gfx/icon16/heart_add.png | Bin 0 -> 820 bytes .../gfx/icon16/heart_delete.png | Bin 0 -> 823 bytes base/resources.pk3dir/gfx/icon16/help.png | Bin 0 -> 786 bytes .../resources.pk3dir/gfx/icon16/hourglass.png | Bin 0 -> 744 bytes .../gfx/icon16/hourglass_add.png | Bin 0 -> 814 bytes .../gfx/icon16/hourglass_delete.png | Bin 0 -> 829 bytes .../gfx/icon16/hourglass_go.png | Bin 0 -> 866 bytes .../gfx/icon16/hourglass_link.png | Bin 0 -> 871 bytes base/resources.pk3dir/gfx/icon16/house.png | Bin 0 -> 806 bytes base/resources.pk3dir/gfx/icon16/house_go.png | Bin 0 -> 861 bytes .../gfx/icon16/house_link.png | Bin 0 -> 868 bytes base/resources.pk3dir/gfx/icon16/html.png | Bin 0 -> 578 bytes base/resources.pk3dir/gfx/icon16/html_add.png | Bin 0 -> 698 bytes .../gfx/icon16/html_delete.png | Bin 0 -> 688 bytes base/resources.pk3dir/gfx/icon16/html_go.png | Bin 0 -> 692 bytes .../gfx/icon16/html_valid.png | Bin 0 -> 704 bytes base/resources.pk3dir/gfx/icon16/image.png | Bin 0 -> 516 bytes .../resources.pk3dir/gfx/icon16/image_add.png | Bin 0 -> 653 bytes .../gfx/icon16/image_delete.png | Bin 0 -> 653 bytes .../gfx/icon16/image_edit.png | Bin 0 -> 783 bytes .../gfx/icon16/image_link.png | Bin 0 -> 773 bytes base/resources.pk3dir/gfx/icon16/images.png | Bin 0 -> 661 bytes .../gfx/icon16/information.png | Bin 0 -> 778 bytes base/resources.pk3dir/gfx/icon16/ipod.png | Bin 0 -> 463 bytes .../resources.pk3dir/gfx/icon16/ipod_cast.png | Bin 0 -> 711 bytes .../gfx/icon16/ipod_cast_add.png | Bin 0 -> 796 bytes .../gfx/icon16/ipod_cast_delete.png | Bin 0 -> 809 bytes .../gfx/icon16/ipod_sound.png | Bin 0 -> 678 bytes base/resources.pk3dir/gfx/icon16/joystick.png | Bin 0 -> 559 bytes .../gfx/icon16/joystick_add.png | Bin 0 -> 669 bytes .../gfx/icon16/joystick_delete.png | Bin 0 -> 671 bytes .../gfx/icon16/joystick_error.png | Bin 0 -> 711 bytes base/resources.pk3dir/gfx/icon16/key.png | Bin 0 -> 612 bytes base/resources.pk3dir/gfx/icon16/key_add.png | Bin 0 -> 703 bytes .../gfx/icon16/key_delete.png | Bin 0 -> 724 bytes base/resources.pk3dir/gfx/icon16/key_go.png | Bin 0 -> 744 bytes base/resources.pk3dir/gfx/icon16/keyboard.png | Bin 0 -> 570 bytes .../gfx/icon16/keyboard_add.png | Bin 0 -> 683 bytes .../gfx/icon16/keyboard_delete.png | Bin 0 -> 681 bytes .../gfx/icon16/keyboard_magnify.png | Bin 0 -> 651 bytes base/resources.pk3dir/gfx/icon16/layers.png | Bin 0 -> 597 bytes base/resources.pk3dir/gfx/icon16/layout.png | Bin 0 -> 480 bytes .../gfx/icon16/layout_add.png | Bin 0 -> 577 bytes .../gfx/icon16/layout_content.png | Bin 0 -> 519 bytes .../gfx/icon16/layout_delete.png | Bin 0 -> 608 bytes .../gfx/icon16/layout_edit.png | Bin 0 -> 716 bytes .../gfx/icon16/layout_error.png | Bin 0 -> 666 bytes .../gfx/icon16/layout_header.png | Bin 0 -> 500 bytes .../gfx/icon16/layout_link.png | Bin 0 -> 660 bytes .../gfx/icon16/layout_sidebar.png | Bin 0 -> 479 bytes .../resources.pk3dir/gfx/icon16/lightbulb.png | Bin 0 -> 699 bytes .../gfx/icon16/lightbulb_add.png | Bin 0 -> 779 bytes .../gfx/icon16/lightbulb_delete.png | Bin 0 -> 783 bytes .../gfx/icon16/lightbulb_off.png | Bin 0 -> 742 bytes .../resources.pk3dir/gfx/icon16/lightning.png | Bin 0 -> 634 bytes .../gfx/icon16/lightning_add.png | Bin 0 -> 746 bytes .../gfx/icon16/lightning_delete.png | Bin 0 -> 745 bytes .../gfx/icon16/lightning_go.png | Bin 0 -> 739 bytes base/resources.pk3dir/gfx/icon16/link.png | Bin 0 -> 343 bytes base/resources.pk3dir/gfx/icon16/link_add.png | Bin 0 -> 570 bytes .../gfx/icon16/link_break.png | Bin 0 -> 657 bytes .../gfx/icon16/link_delete.png | Bin 0 -> 600 bytes .../resources.pk3dir/gfx/icon16/link_edit.png | Bin 0 -> 703 bytes .../gfx/icon16/link_error.png | Bin 0 -> 698 bytes base/resources.pk3dir/gfx/icon16/link_go.png | Bin 0 -> 655 bytes base/resources.pk3dir/gfx/icon16/lock.png | Bin 0 -> 749 bytes base/resources.pk3dir/gfx/icon16/lock_add.png | Bin 0 -> 824 bytes .../gfx/icon16/lock_break.png | Bin 0 -> 771 bytes .../gfx/icon16/lock_delete.png | Bin 0 -> 815 bytes .../resources.pk3dir/gfx/icon16/lock_edit.png | Bin 0 -> 861 bytes base/resources.pk3dir/gfx/icon16/lock_go.png | Bin 0 -> 829 bytes .../resources.pk3dir/gfx/icon16/lock_open.png | Bin 0 -> 727 bytes base/resources.pk3dir/gfx/icon16/lorry.png | Bin 0 -> 582 bytes .../resources.pk3dir/gfx/icon16/lorry_add.png | Bin 0 -> 689 bytes .../gfx/icon16/lorry_delete.png | Bin 0 -> 683 bytes .../gfx/icon16/lorry_error.png | Bin 0 -> 739 bytes .../gfx/icon16/lorry_flatbed.png | Bin 0 -> 450 bytes base/resources.pk3dir/gfx/icon16/lorry_go.png | Bin 0 -> 699 bytes .../gfx/icon16/lorry_link.png | Bin 0 -> 775 bytes .../resources.pk3dir/gfx/icon16/magnifier.png | Bin 0 -> 615 bytes .../gfx/icon16/magnifier_zoom_in.png | Bin 0 -> 680 bytes .../gfx/icon16/magnifier_zoom_out.png | Bin 0 -> 657 bytes base/resources.pk3dir/gfx/icon16/male.png | Bin 0 -> 629 bytes base/resources.pk3dir/gfx/icon16/map.png | Bin 0 -> 804 bytes base/resources.pk3dir/gfx/icon16/map_add.png | Bin 0 -> 836 bytes .../gfx/icon16/map_delete.png | Bin 0 -> 835 bytes base/resources.pk3dir/gfx/icon16/map_edit.png | Bin 0 -> 876 bytes base/resources.pk3dir/gfx/icon16/map_go.png | Bin 0 -> 842 bytes .../gfx/icon16/map_magnify.png | Bin 0 -> 797 bytes .../gfx/icon16/medal_bronze_1.png | Bin 0 -> 640 bytes .../gfx/icon16/medal_bronze_2.png | Bin 0 -> 654 bytes .../gfx/icon16/medal_bronze_3.png | Bin 0 -> 646 bytes .../gfx/icon16/medal_bronze_add.png | Bin 0 -> 747 bytes .../gfx/icon16/medal_bronze_delete.png | Bin 0 -> 730 bytes .../gfx/icon16/medal_gold_1.png | Bin 0 -> 629 bytes .../gfx/icon16/medal_gold_2.png | Bin 0 -> 641 bytes .../gfx/icon16/medal_gold_3.png | Bin 0 -> 634 bytes .../gfx/icon16/medal_gold_add.png | Bin 0 -> 733 bytes .../gfx/icon16/medal_gold_delete.png | Bin 0 -> 724 bytes .../gfx/icon16/medal_silver_1.png | Bin 0 -> 589 bytes .../gfx/icon16/medal_silver_2.png | Bin 0 -> 600 bytes .../gfx/icon16/medal_silver_3.png | Bin 0 -> 597 bytes .../gfx/icon16/medal_silver_add.png | Bin 0 -> 727 bytes .../gfx/icon16/medal_silver_delete.png | Bin 0 -> 714 bytes base/resources.pk3dir/gfx/icon16/money.png | Bin 0 -> 738 bytes .../resources.pk3dir/gfx/icon16/money_add.png | Bin 0 -> 784 bytes .../gfx/icon16/money_delete.png | Bin 0 -> 806 bytes .../gfx/icon16/money_dollar.png | Bin 0 -> 630 bytes .../gfx/icon16/money_euro.png | Bin 0 -> 605 bytes .../gfx/icon16/money_pound.png | Bin 0 -> 565 bytes .../resources.pk3dir/gfx/icon16/money_yen.png | Bin 0 -> 562 bytes base/resources.pk3dir/gfx/icon16/monitor.png | Bin 0 -> 612 bytes .../gfx/icon16/monitor_add.png | Bin 0 -> 692 bytes .../gfx/icon16/monitor_delete.png | Bin 0 -> 691 bytes .../gfx/icon16/monitor_edit.png | Bin 0 -> 769 bytes .../gfx/icon16/monitor_error.png | Bin 0 -> 714 bytes .../gfx/icon16/monitor_go.png | Bin 0 -> 696 bytes .../gfx/icon16/monitor_lightning.png | Bin 0 -> 768 bytes .../gfx/icon16/monitor_link.png | Bin 0 -> 736 bytes base/resources.pk3dir/gfx/icon16/mouse.png | Bin 0 -> 634 bytes .../resources.pk3dir/gfx/icon16/mouse_add.png | Bin 0 -> 729 bytes .../gfx/icon16/mouse_delete.png | Bin 0 -> 741 bytes .../gfx/icon16/mouse_error.png | Bin 0 -> 790 bytes base/resources.pk3dir/gfx/icon16/music.png | Bin 0 -> 385 bytes base/resources.pk3dir/gfx/icon16/new.png | Bin 0 -> 378 bytes .../resources.pk3dir/gfx/icon16/newspaper.png | Bin 0 -> 658 bytes .../gfx/icon16/newspaper_add.png | Bin 0 -> 750 bytes .../gfx/icon16/newspaper_delete.png | Bin 0 -> 775 bytes .../gfx/icon16/newspaper_go.png | Bin 0 -> 779 bytes .../gfx/icon16/newspaper_link.png | Bin 0 -> 787 bytes base/resources.pk3dir/gfx/icon16/note.png | Bin 0 -> 500 bytes base/resources.pk3dir/gfx/icon16/note_add.png | Bin 0 -> 641 bytes .../gfx/icon16/note_delete.png | Bin 0 -> 631 bytes .../resources.pk3dir/gfx/icon16/note_edit.png | Bin 0 -> 731 bytes .../gfx/icon16/note_error.png | Bin 0 -> 680 bytes base/resources.pk3dir/gfx/icon16/note_go.png | Bin 0 -> 661 bytes base/resources.pk3dir/gfx/icon16/package.png | Bin 0 -> 853 bytes .../gfx/icon16/package_add.png | Bin 0 -> 899 bytes .../gfx/icon16/package_delete.png | Bin 0 -> 891 bytes .../gfx/icon16/package_go.png | Bin 0 -> 898 bytes .../gfx/icon16/package_green.png | Bin 0 -> 896 bytes .../gfx/icon16/package_link.png | Bin 0 -> 939 bytes base/resources.pk3dir/gfx/icon16/page.png | Bin 0 -> 635 bytes base/resources.pk3dir/gfx/icon16/page_add.png | Bin 0 -> 739 bytes .../gfx/icon16/page_attach.png | Bin 0 -> 794 bytes .../resources.pk3dir/gfx/icon16/page_code.png | Bin 0 -> 818 bytes .../resources.pk3dir/gfx/icon16/page_copy.png | Bin 0 -> 663 bytes .../gfx/icon16/page_delete.png | Bin 0 -> 740 bytes .../resources.pk3dir/gfx/icon16/page_edit.png | Bin 0 -> 807 bytes .../gfx/icon16/page_error.png | Bin 0 -> 793 bytes .../gfx/icon16/page_excel.png | Bin 0 -> 817 bytes .../resources.pk3dir/gfx/icon16/page_find.png | Bin 0 -> 879 bytes .../resources.pk3dir/gfx/icon16/page_gear.png | Bin 0 -> 833 bytes base/resources.pk3dir/gfx/icon16/page_go.png | Bin 0 -> 779 bytes .../gfx/icon16/page_green.png | Bin 0 -> 621 bytes base/resources.pk3dir/gfx/icon16/page_key.png | Bin 0 -> 801 bytes .../gfx/icon16/page_lightning.png | Bin 0 -> 839 bytes .../resources.pk3dir/gfx/icon16/page_link.png | Bin 0 -> 830 bytes .../gfx/icon16/page_paintbrush.png | Bin 0 -> 813 bytes .../gfx/icon16/page_paste.png | Bin 0 -> 703 bytes base/resources.pk3dir/gfx/icon16/page_red.png | Bin 0 -> 641 bytes .../gfx/icon16/page_refresh.png | Bin 0 -> 858 bytes .../resources.pk3dir/gfx/icon16/page_save.png | Bin 0 -> 774 bytes .../gfx/icon16/page_white.png | Bin 0 -> 294 bytes .../gfx/icon16/page_white_acrobat.png | Bin 0 -> 591 bytes .../gfx/icon16/page_white_actionscript.png | Bin 0 -> 664 bytes .../gfx/icon16/page_white_add.png | Bin 0 -> 512 bytes .../gfx/icon16/page_white_c.png | Bin 0 -> 587 bytes .../gfx/icon16/page_white_camera.png | Bin 0 -> 656 bytes .../gfx/icon16/page_white_cd.png | Bin 0 -> 666 bytes .../gfx/icon16/page_white_code.png | Bin 0 -> 603 bytes .../gfx/icon16/page_white_code_red.png | Bin 0 -> 587 bytes .../gfx/icon16/page_white_coldfusion.png | Bin 0 -> 592 bytes .../gfx/icon16/page_white_compressed.png | Bin 0 -> 724 bytes .../gfx/icon16/page_white_copy.png | Bin 0 -> 309 bytes .../gfx/icon16/page_white_cplusplus.png | Bin 0 -> 621 bytes .../gfx/icon16/page_white_csharp.png | Bin 0 -> 700 bytes .../gfx/icon16/page_white_cup.png | Bin 0 -> 639 bytes .../gfx/icon16/page_white_database.png | Bin 0 -> 579 bytes .../gfx/icon16/page_white_delete.png | Bin 0 -> 536 bytes .../gfx/icon16/page_white_dvd.png | Bin 0 -> 638 bytes .../gfx/icon16/page_white_edit.png | Bin 0 -> 618 bytes .../gfx/icon16/page_white_error.png | Bin 0 -> 623 bytes .../gfx/icon16/page_white_excel.png | Bin 0 -> 663 bytes .../gfx/icon16/page_white_find.png | Bin 0 -> 676 bytes .../gfx/icon16/page_white_flash.png | Bin 0 -> 582 bytes .../gfx/icon16/page_white_freehand.png | Bin 0 -> 639 bytes .../gfx/icon16/page_white_gear.png | Bin 0 -> 402 bytes .../gfx/icon16/page_white_get.png | Bin 0 -> 516 bytes .../gfx/icon16/page_white_go.png | Bin 0 -> 612 bytes .../gfx/icon16/page_white_h.png | Bin 0 -> 603 bytes .../gfx/icon16/page_white_horizontal.png | Bin 0 -> 296 bytes .../gfx/icon16/page_white_key.png | Bin 0 -> 616 bytes .../gfx/icon16/page_white_lightning.png | Bin 0 -> 669 bytes .../gfx/icon16/page_white_link.png | Bin 0 -> 614 bytes .../gfx/icon16/page_white_magnify.png | Bin 0 -> 554 bytes .../gfx/icon16/page_white_medal.png | Bin 0 -> 706 bytes .../gfx/icon16/page_white_office.png | Bin 0 -> 779 bytes .../gfx/icon16/page_white_paint.png | Bin 0 -> 688 bytes .../gfx/icon16/page_white_paintbrush.png | Bin 0 -> 618 bytes .../gfx/icon16/page_white_paste.png | Bin 0 -> 620 bytes .../gfx/icon16/page_white_php.png | Bin 0 -> 538 bytes .../gfx/icon16/page_white_picture.png | Bin 0 -> 650 bytes .../gfx/icon16/page_white_powerpoint.png | Bin 0 -> 588 bytes .../gfx/icon16/page_white_put.png | Bin 0 -> 523 bytes .../gfx/icon16/page_white_ruby.png | Bin 0 -> 626 bytes .../gfx/icon16/page_white_stack.png | Bin 0 -> 317 bytes .../gfx/icon16/page_white_star.png | Bin 0 -> 565 bytes .../gfx/icon16/page_white_swoosh.png | Bin 0 -> 634 bytes .../gfx/icon16/page_white_text.png | Bin 0 -> 342 bytes .../gfx/icon16/page_white_text_width.png | Bin 0 -> 315 bytes .../gfx/icon16/page_white_tux.png | Bin 0 -> 668 bytes .../gfx/icon16/page_white_vector.png | Bin 0 -> 644 bytes .../gfx/icon16/page_white_visualstudio.png | Bin 0 -> 702 bytes .../gfx/icon16/page_white_width.png | Bin 0 -> 309 bytes .../gfx/icon16/page_white_word.png | Bin 0 -> 651 bytes .../gfx/icon16/page_white_world.png | Bin 0 -> 734 bytes .../gfx/icon16/page_white_wrench.png | Bin 0 -> 613 bytes .../gfx/icon16/page_white_zip.png | Bin 0 -> 386 bytes .../resources.pk3dir/gfx/icon16/page_word.png | Bin 0 -> 777 bytes .../gfx/icon16/page_world.png | Bin 0 -> 903 bytes .../gfx/icon16/paintbrush.png | Bin 0 -> 548 bytes base/resources.pk3dir/gfx/icon16/paintcan.png | Bin 0 -> 707 bytes base/resources.pk3dir/gfx/icon16/palette.png | Bin 0 -> 856 bytes .../gfx/icon16/paste_plain.png | Bin 0 -> 605 bytes .../gfx/icon16/paste_word.png | Bin 0 -> 701 bytes base/resources.pk3dir/gfx/icon16/pencil.png | Bin 0 -> 450 bytes .../gfx/icon16/pencil_add.png | Bin 0 -> 589 bytes .../gfx/icon16/pencil_delete.png | Bin 0 -> 603 bytes .../resources.pk3dir/gfx/icon16/pencil_go.png | Bin 0 -> 666 bytes base/resources.pk3dir/gfx/icon16/phone.png | Bin 0 -> 488 bytes .../resources.pk3dir/gfx/icon16/phone_add.png | Bin 0 -> 621 bytes .../gfx/icon16/phone_delete.png | Bin 0 -> 615 bytes .../gfx/icon16/phone_sound.png | Bin 0 -> 703 bytes base/resources.pk3dir/gfx/icon16/photo.png | Bin 0 -> 589 bytes .../resources.pk3dir/gfx/icon16/photo_add.png | Bin 0 -> 707 bytes .../gfx/icon16/photo_delete.png | Bin 0 -> 703 bytes .../gfx/icon16/photo_link.png | Bin 0 -> 784 bytes base/resources.pk3dir/gfx/icon16/photos.png | Bin 0 -> 647 bytes base/resources.pk3dir/gfx/icon16/picture.png | Bin 0 -> 606 bytes .../gfx/icon16/picture_add.png | Bin 0 -> 745 bytes .../gfx/icon16/picture_delete.png | Bin 0 -> 744 bytes .../gfx/icon16/picture_edit.png | Bin 0 -> 826 bytes .../gfx/icon16/picture_empty.png | Bin 0 -> 463 bytes .../gfx/icon16/picture_error.png | Bin 0 -> 755 bytes .../gfx/icon16/picture_go.png | Bin 0 -> 758 bytes .../gfx/icon16/picture_key.png | Bin 0 -> 794 bytes .../gfx/icon16/picture_link.png | Bin 0 -> 835 bytes .../gfx/icon16/picture_save.png | Bin 0 -> 755 bytes base/resources.pk3dir/gfx/icon16/pictures.png | Bin 0 -> 704 bytes base/resources.pk3dir/gfx/icon16/pilcrow.png | Bin 0 -> 361 bytes base/resources.pk3dir/gfx/icon16/pill.png | Bin 0 -> 719 bytes base/resources.pk3dir/gfx/icon16/pill_add.png | Bin 0 -> 797 bytes .../gfx/icon16/pill_delete.png | Bin 0 -> 805 bytes base/resources.pk3dir/gfx/icon16/pill_go.png | Bin 0 -> 817 bytes base/resources.pk3dir/gfx/icon16/plugin.png | Bin 0 -> 591 bytes .../gfx/icon16/plugin_add.png | Bin 0 -> 691 bytes .../gfx/icon16/plugin_delete.png | Bin 0 -> 692 bytes .../gfx/icon16/plugin_disabled.png | Bin 0 -> 347 bytes .../gfx/icon16/plugin_edit.png | Bin 0 -> 746 bytes .../gfx/icon16/plugin_error.png | Bin 0 -> 702 bytes .../resources.pk3dir/gfx/icon16/plugin_go.png | Bin 0 -> 694 bytes .../gfx/icon16/plugin_link.png | Bin 0 -> 759 bytes base/resources.pk3dir/gfx/icon16/printer.png | Bin 0 -> 731 bytes .../gfx/icon16/printer_add.png | Bin 0 -> 782 bytes .../gfx/icon16/printer_delete.png | Bin 0 -> 792 bytes .../gfx/icon16/printer_empty.png | Bin 0 -> 350 bytes .../gfx/icon16/printer_error.png | Bin 0 -> 854 bytes base/resources.pk3dir/gfx/icon16/rainbow.png | Bin 0 -> 655 bytes base/resources.pk3dir/gfx/icon16/report.png | Bin 0 -> 649 bytes .../gfx/icon16/report_add.png | Bin 0 -> 714 bytes .../gfx/icon16/report_delete.png | Bin 0 -> 729 bytes .../gfx/icon16/report_disk.png | Bin 0 -> 760 bytes .../gfx/icon16/report_edit.png | Bin 0 -> 762 bytes .../resources.pk3dir/gfx/icon16/report_go.png | Bin 0 -> 756 bytes .../gfx/icon16/report_key.png | Bin 0 -> 760 bytes .../gfx/icon16/report_link.png | Bin 0 -> 754 bytes .../gfx/icon16/report_magnify.png | Bin 0 -> 738 bytes .../gfx/icon16/report_picture.png | Bin 0 -> 733 bytes .../gfx/icon16/report_user.png | Bin 0 -> 785 bytes .../gfx/icon16/report_word.png | Bin 0 -> 731 bytes .../gfx/icon16/resultset_first.png | Bin 0 -> 522 bytes .../gfx/icon16/resultset_last.png | Bin 0 -> 524 bytes .../gfx/icon16/resultset_next.png | Bin 0 -> 395 bytes .../gfx/icon16/resultset_previous.png | Bin 0 -> 389 bytes base/resources.pk3dir/gfx/icon16/rosette.png | Bin 0 -> 673 bytes base/resources.pk3dir/gfx/icon16/rss.png | Bin 0 -> 530 bytes base/resources.pk3dir/gfx/icon16/rss_add.png | Bin 0 -> 649 bytes .../gfx/icon16/rss_delete.png | Bin 0 -> 633 bytes base/resources.pk3dir/gfx/icon16/rss_go.png | Bin 0 -> 635 bytes .../resources.pk3dir/gfx/icon16/rss_valid.png | Bin 0 -> 660 bytes base/resources.pk3dir/gfx/icon16/ruby.png | Bin 0 -> 592 bytes base/resources.pk3dir/gfx/icon16/ruby_add.png | Bin 0 -> 691 bytes .../gfx/icon16/ruby_delete.png | Bin 0 -> 704 bytes .../resources.pk3dir/gfx/icon16/ruby_gear.png | Bin 0 -> 716 bytes base/resources.pk3dir/gfx/icon16/ruby_get.png | Bin 0 -> 692 bytes base/resources.pk3dir/gfx/icon16/ruby_go.png | Bin 0 -> 720 bytes base/resources.pk3dir/gfx/icon16/ruby_key.png | Bin 0 -> 732 bytes .../resources.pk3dir/gfx/icon16/ruby_link.png | Bin 0 -> 767 bytes base/resources.pk3dir/gfx/icon16/ruby_put.png | Bin 0 -> 694 bytes base/resources.pk3dir/gfx/icon16/script.png | Bin 0 -> 748 bytes .../gfx/icon16/script_add.png | Bin 0 -> 811 bytes .../gfx/icon16/script_code.png | Bin 0 -> 859 bytes .../gfx/icon16/script_code_red.png | Bin 0 -> 868 bytes .../gfx/icon16/script_delete.png | Bin 0 -> 811 bytes .../gfx/icon16/script_edit.png | Bin 0 -> 880 bytes .../gfx/icon16/script_error.png | Bin 0 -> 861 bytes .../gfx/icon16/script_gear.png | Bin 0 -> 861 bytes .../resources.pk3dir/gfx/icon16/script_go.png | Bin 0 -> 839 bytes .../gfx/icon16/script_key.png | Bin 0 -> 853 bytes .../gfx/icon16/script_lightning.png | Bin 0 -> 879 bytes .../gfx/icon16/script_link.png | Bin 0 -> 876 bytes .../gfx/icon16/script_palette.png | Bin 0 -> 917 bytes .../gfx/icon16/script_save.png | Bin 0 -> 804 bytes base/resources.pk3dir/gfx/icon16/server.png | Bin 0 -> 530 bytes .../gfx/icon16/server_add.png | Bin 0 -> 676 bytes .../gfx/icon16/server_chart.png | Bin 0 -> 673 bytes .../gfx/icon16/server_compressed.png | Bin 0 -> 721 bytes .../gfx/icon16/server_connect.png | Bin 0 -> 755 bytes .../gfx/icon16/server_database.png | Bin 0 -> 666 bytes .../gfx/icon16/server_delete.png | Bin 0 -> 668 bytes .../gfx/icon16/server_edit.png | Bin 0 -> 749 bytes .../gfx/icon16/server_error.png | Bin 0 -> 678 bytes .../resources.pk3dir/gfx/icon16/server_go.png | Bin 0 -> 706 bytes .../gfx/icon16/server_key.png | Bin 0 -> 746 bytes .../gfx/icon16/server_lightning.png | Bin 0 -> 729 bytes .../gfx/icon16/server_link.png | Bin 0 -> 706 bytes .../gfx/icon16/server_uncompressed.png | Bin 0 -> 669 bytes base/resources.pk3dir/gfx/icon16/shading.png | Bin 0 -> 225 bytes .../gfx/icon16/shape_align_bottom.png | Bin 0 -> 398 bytes .../gfx/icon16/shape_align_center.png | Bin 0 -> 384 bytes .../gfx/icon16/shape_align_left.png | Bin 0 -> 402 bytes .../gfx/icon16/shape_align_middle.png | Bin 0 -> 414 bytes .../gfx/icon16/shape_align_right.png | Bin 0 -> 401 bytes .../gfx/icon16/shape_align_top.png | Bin 0 -> 406 bytes .../gfx/icon16/shape_flip_horizontal.png | Bin 0 -> 403 bytes .../gfx/icon16/shape_flip_vertical.png | Bin 0 -> 418 bytes .../gfx/icon16/shape_group.png | Bin 0 -> 553 bytes .../gfx/icon16/shape_handles.png | Bin 0 -> 538 bytes .../gfx/icon16/shape_move_back.png | Bin 0 -> 395 bytes .../gfx/icon16/shape_move_backwards.png | Bin 0 -> 358 bytes .../gfx/icon16/shape_move_forwards.png | Bin 0 -> 381 bytes .../gfx/icon16/shape_move_front.png | Bin 0 -> 435 bytes .../gfx/icon16/shape_rotate_anticlockwise.png | Bin 0 -> 657 bytes .../gfx/icon16/shape_rotate_clockwise.png | Bin 0 -> 673 bytes .../gfx/icon16/shape_square.png | Bin 0 -> 353 bytes .../gfx/icon16/shape_square_add.png | Bin 0 -> 539 bytes .../gfx/icon16/shape_square_delete.png | Bin 0 -> 537 bytes .../gfx/icon16/shape_square_edit.png | Bin 0 -> 660 bytes .../gfx/icon16/shape_square_error.png | Bin 0 -> 570 bytes .../gfx/icon16/shape_square_go.png | Bin 0 -> 566 bytes .../gfx/icon16/shape_square_key.png | Bin 0 -> 607 bytes .../gfx/icon16/shape_square_link.png | Bin 0 -> 642 bytes .../gfx/icon16/shape_ungroup.png | Bin 0 -> 666 bytes base/resources.pk3dir/gfx/icon16/shield.png | Bin 0 -> 702 bytes .../gfx/icon16/shield_add.png | Bin 0 -> 758 bytes .../gfx/icon16/shield_delete.png | Bin 0 -> 768 bytes .../resources.pk3dir/gfx/icon16/shield_go.png | Bin 0 -> 775 bytes base/resources.pk3dir/gfx/icon16/sitemap.png | Bin 0 -> 278 bytes .../gfx/icon16/sitemap_color.png | Bin 0 -> 406 bytes base/resources.pk3dir/gfx/icon16/sound.png | Bin 0 -> 610 bytes .../resources.pk3dir/gfx/icon16/sound_add.png | Bin 0 -> 684 bytes .../gfx/icon16/sound_delete.png | Bin 0 -> 711 bytes .../resources.pk3dir/gfx/icon16/sound_low.png | Bin 0 -> 524 bytes .../gfx/icon16/sound_mute.png | Bin 0 -> 474 bytes .../gfx/icon16/sound_none.png | Bin 0 -> 417 bytes .../gfx/icon16/spellcheck.png | Bin 0 -> 603 bytes .../gfx/icon16/sport_8ball.png | Bin 0 -> 490 bytes .../gfx/icon16/sport_basketball.png | Bin 0 -> 977 bytes .../gfx/icon16/sport_football.png | Bin 0 -> 875 bytes .../gfx/icon16/sport_golf.png | Bin 0 -> 504 bytes .../gfx/icon16/sport_raquet.png | Bin 0 -> 719 bytes .../gfx/icon16/sport_shuttlecock.png | Bin 0 -> 683 bytes .../gfx/icon16/sport_soccer.png | Bin 0 -> 517 bytes .../gfx/icon16/sport_tennis.png | Bin 0 -> 884 bytes base/resources.pk3dir/gfx/icon16/star.png | Bin 0 -> 670 bytes .../gfx/icon16/status_away.png | Bin 0 -> 794 bytes .../gfx/icon16/status_busy.png | Bin 0 -> 751 bytes .../gfx/icon16/status_offline.png | Bin 0 -> 422 bytes .../gfx/icon16/status_online.png | Bin 0 -> 722 bytes base/resources.pk3dir/gfx/icon16/stop.png | Bin 0 -> 700 bytes base/resources.pk3dir/gfx/icon16/style.png | Bin 0 -> 813 bytes .../resources.pk3dir/gfx/icon16/style_add.png | Bin 0 -> 844 bytes .../gfx/icon16/style_delete.png | Bin 0 -> 865 bytes .../gfx/icon16/style_edit.png | Bin 0 -> 927 bytes base/resources.pk3dir/gfx/icon16/style_go.png | Bin 0 -> 862 bytes base/resources.pk3dir/gfx/icon16/sum.png | Bin 0 -> 289 bytes base/resources.pk3dir/gfx/icon16/tab.png | Bin 0 -> 323 bytes base/resources.pk3dir/gfx/icon16/tab_add.png | Bin 0 -> 488 bytes .../gfx/icon16/tab_delete.png | Bin 0 -> 493 bytes base/resources.pk3dir/gfx/icon16/tab_edit.png | Bin 0 -> 580 bytes base/resources.pk3dir/gfx/icon16/tab_go.png | Bin 0 -> 552 bytes base/resources.pk3dir/gfx/icon16/table.png | Bin 0 -> 566 bytes .../resources.pk3dir/gfx/icon16/table_add.png | Bin 0 -> 663 bytes .../gfx/icon16/table_delete.png | Bin 0 -> 660 bytes .../gfx/icon16/table_edit.png | Bin 0 -> 744 bytes .../gfx/icon16/table_error.png | Bin 0 -> 687 bytes .../gfx/icon16/table_gear.png | Bin 0 -> 714 bytes base/resources.pk3dir/gfx/icon16/table_go.png | Bin 0 -> 683 bytes .../resources.pk3dir/gfx/icon16/table_key.png | Bin 0 -> 746 bytes .../gfx/icon16/table_lightning.png | Bin 0 -> 736 bytes .../gfx/icon16/table_link.png | Bin 0 -> 728 bytes .../gfx/icon16/table_multiple.png | Bin 0 -> 612 bytes .../gfx/icon16/table_refresh.png | Bin 0 -> 795 bytes .../gfx/icon16/table_relationship.png | Bin 0 -> 663 bytes .../gfx/icon16/table_row_delete.png | Bin 0 -> 629 bytes .../gfx/icon16/table_row_insert.png | Bin 0 -> 641 bytes .../gfx/icon16/table_save.png | Bin 0 -> 723 bytes .../gfx/icon16/table_sort.png | Bin 0 -> 678 bytes base/resources.pk3dir/gfx/icon16/tag.png | Bin 0 -> 389 bytes base/resources.pk3dir/gfx/icon16/tag_blue.png | Bin 0 -> 586 bytes .../gfx/icon16/tag_blue_add.png | Bin 0 -> 671 bytes .../gfx/icon16/tag_blue_delete.png | Bin 0 -> 701 bytes .../gfx/icon16/tag_blue_edit.png | Bin 0 -> 748 bytes .../resources.pk3dir/gfx/icon16/tag_green.png | Bin 0 -> 613 bytes .../gfx/icon16/tag_orange.png | Bin 0 -> 586 bytes base/resources.pk3dir/gfx/icon16/tag_pink.png | Bin 0 -> 579 bytes .../gfx/icon16/tag_purple.png | Bin 0 -> 599 bytes base/resources.pk3dir/gfx/icon16/tag_red.png | Bin 0 -> 592 bytes .../gfx/icon16/tag_yellow.png | Bin 0 -> 586 bytes .../resources.pk3dir/gfx/icon16/telephone.png | Bin 0 -> 791 bytes .../gfx/icon16/telephone_add.png | Bin 0 -> 860 bytes .../gfx/icon16/telephone_delete.png | Bin 0 -> 856 bytes .../gfx/icon16/telephone_edit.png | Bin 0 -> 893 bytes .../gfx/icon16/telephone_error.png | Bin 0 -> 884 bytes .../gfx/icon16/telephone_go.png | Bin 0 -> 865 bytes .../gfx/icon16/telephone_key.png | Bin 0 -> 881 bytes .../gfx/icon16/telephone_link.png | Bin 0 -> 909 bytes .../gfx/icon16/television.png | Bin 0 -> 696 bytes .../gfx/icon16/television_add.png | Bin 0 -> 809 bytes .../gfx/icon16/television_delete.png | Bin 0 -> 810 bytes .../gfx/icon16/text_align_center.png | Bin 0 -> 234 bytes .../gfx/icon16/text_align_justify.png | Bin 0 -> 209 bytes .../gfx/icon16/text_align_left.png | Bin 0 -> 209 bytes .../gfx/icon16/text_align_right.png | Bin 0 -> 209 bytes .../gfx/icon16/text_allcaps.png | Bin 0 -> 284 bytes .../resources.pk3dir/gfx/icon16/text_bold.png | Bin 0 -> 304 bytes .../gfx/icon16/text_columns.png | Bin 0 -> 246 bytes .../gfx/icon16/text_dropcaps.png | Bin 0 -> 314 bytes .../gfx/icon16/text_heading_1.png | Bin 0 -> 276 bytes .../gfx/icon16/text_heading_2.png | Bin 0 -> 304 bytes .../gfx/icon16/text_heading_3.png | Bin 0 -> 306 bytes .../gfx/icon16/text_heading_4.png | Bin 0 -> 293 bytes .../gfx/icon16/text_heading_5.png | Bin 0 -> 304 bytes .../gfx/icon16/text_heading_6.png | Bin 0 -> 310 bytes .../gfx/icon16/text_horizontalrule.png | Bin 0 -> 317 bytes .../gfx/icon16/text_indent.png | Bin 0 -> 353 bytes .../gfx/icon16/text_indent_remove.png | Bin 0 -> 351 bytes .../gfx/icon16/text_italic.png | Bin 0 -> 223 bytes .../gfx/icon16/text_kerning.png | Bin 0 -> 495 bytes .../gfx/icon16/text_letter_omega.png | Bin 0 -> 541 bytes .../gfx/icon16/text_letterspacing.png | Bin 0 -> 503 bytes .../gfx/icon16/text_linespacing.png | Bin 0 -> 363 bytes .../gfx/icon16/text_list_bullets.png | Bin 0 -> 344 bytes .../gfx/icon16/text_list_numbers.png | Bin 0 -> 357 bytes .../gfx/icon16/text_lowercase.png | Bin 0 -> 709 bytes .../gfx/icon16/text_padding_bottom.png | Bin 0 -> 237 bytes .../gfx/icon16/text_padding_left.png | Bin 0 -> 271 bytes .../gfx/icon16/text_padding_right.png | Bin 0 -> 271 bytes .../gfx/icon16/text_padding_top.png | Bin 0 -> 236 bytes .../gfx/icon16/text_replace.png | Bin 0 -> 691 bytes .../gfx/icon16/text_signature.png | Bin 0 -> 524 bytes .../gfx/icon16/text_smallcaps.png | Bin 0 -> 260 bytes .../gfx/icon16/text_strikethrough.png | Bin 0 -> 269 bytes .../gfx/icon16/text_subscript.png | Bin 0 -> 422 bytes .../gfx/icon16/text_superscript.png | Bin 0 -> 421 bytes .../gfx/icon16/text_underline.png | Bin 0 -> 273 bytes .../gfx/icon16/text_uppercase.png | Bin 0 -> 747 bytes .../resources.pk3dir/gfx/icon16/textfield.png | Bin 0 -> 153 bytes .../gfx/icon16/textfield_add.png | Bin 0 -> 321 bytes .../gfx/icon16/textfield_delete.png | Bin 0 -> 335 bytes .../gfx/icon16/textfield_key.png | Bin 0 -> 455 bytes .../gfx/icon16/textfield_rename.png | Bin 0 -> 273 bytes .../gfx/icon16/thumb_down.png | Bin 0 -> 601 bytes base/resources.pk3dir/gfx/icon16/thumb_up.png | Bin 0 -> 619 bytes base/resources.pk3dir/gfx/icon16/tick.png | Bin 0 -> 537 bytes base/resources.pk3dir/gfx/icon16/time.png | Bin 0 -> 793 bytes base/resources.pk3dir/gfx/icon16/time_add.png | Bin 0 -> 827 bytes .../gfx/icon16/time_delete.png | Bin 0 -> 853 bytes base/resources.pk3dir/gfx/icon16/time_go.png | Bin 0 -> 882 bytes .../gfx/icon16/timeline_marker.png | Bin 0 -> 327 bytes base/resources.pk3dir/gfx/icon16/transmit.png | Bin 0 -> 749 bytes .../gfx/icon16/transmit_add.png | Bin 0 -> 803 bytes .../gfx/icon16/transmit_blue.png | Bin 0 -> 814 bytes .../gfx/icon16/transmit_delete.png | Bin 0 -> 827 bytes .../gfx/icon16/transmit_edit.png | Bin 0 -> 848 bytes .../gfx/icon16/transmit_error.png | Bin 0 -> 883 bytes .../gfx/icon16/transmit_go.png | Bin 0 -> 842 bytes base/resources.pk3dir/gfx/icon16/tux.png | Bin 0 -> 696 bytes base/resources.pk3dir/gfx/icon16/user.png | Bin 0 -> 741 bytes base/resources.pk3dir/gfx/icon16/user_add.png | Bin 0 -> 746 bytes .../gfx/icon16/user_comment.png | Bin 0 -> 743 bytes .../gfx/icon16/user_delete.png | Bin 0 -> 767 bytes .../resources.pk3dir/gfx/icon16/user_edit.png | Bin 0 -> 833 bytes .../gfx/icon16/user_female.png | Bin 0 -> 663 bytes base/resources.pk3dir/gfx/icon16/user_go.png | Bin 0 -> 793 bytes .../resources.pk3dir/gfx/icon16/user_gray.png | Bin 0 -> 706 bytes .../gfx/icon16/user_green.png | Bin 0 -> 722 bytes .../gfx/icon16/user_orange.png | Bin 0 -> 723 bytes base/resources.pk3dir/gfx/icon16/user_red.png | Bin 0 -> 717 bytes .../resources.pk3dir/gfx/icon16/user_suit.png | Bin 0 -> 748 bytes base/resources.pk3dir/gfx/icon16/vcard.png | Bin 0 -> 533 bytes .../resources.pk3dir/gfx/icon16/vcard_add.png | Bin 0 -> 661 bytes .../gfx/icon16/vcard_delete.png | Bin 0 -> 651 bytes .../gfx/icon16/vcard_edit.png | Bin 0 -> 775 bytes base/resources.pk3dir/gfx/icon16/vector.png | Bin 0 -> 481 bytes .../gfx/icon16/vector_add.png | Bin 0 -> 616 bytes .../gfx/icon16/vector_delete.png | Bin 0 -> 635 bytes base/resources.pk3dir/gfx/icon16/wand.png | Bin 0 -> 570 bytes .../gfx/icon16/weather_clouds.png | Bin 0 -> 581 bytes .../gfx/icon16/weather_cloudy.png | Bin 0 -> 694 bytes .../gfx/icon16/weather_lightning.png | Bin 0 -> 641 bytes .../gfx/icon16/weather_rain.png | Bin 0 -> 626 bytes .../gfx/icon16/weather_snow.png | Bin 0 -> 341 bytes .../gfx/icon16/weather_sun.png | Bin 0 -> 623 bytes base/resources.pk3dir/gfx/icon16/webcam.png | Bin 0 -> 728 bytes .../gfx/icon16/webcam_add.png | Bin 0 -> 786 bytes .../gfx/icon16/webcam_delete.png | Bin 0 -> 805 bytes .../gfx/icon16/webcam_error.png | Bin 0 -> 821 bytes base/resources.pk3dir/gfx/icon16/world.png | Bin 0 -> 923 bytes .../resources.pk3dir/gfx/icon16/world_add.png | Bin 0 -> 940 bytes .../gfx/icon16/world_delete.png | Bin 0 -> 945 bytes .../gfx/icon16/world_edit.png | Bin 0 -> 945 bytes base/resources.pk3dir/gfx/icon16/world_go.png | Bin 0 -> 944 bytes .../gfx/icon16/world_link.png | Bin 0 -> 957 bytes base/resources.pk3dir/gfx/icon16/wrench.png | Bin 0 -> 610 bytes .../gfx/icon16/wrench_orange.png | Bin 0 -> 584 bytes base/resources.pk3dir/gfx/icon16/xhtml.png | Bin 0 -> 595 bytes .../resources.pk3dir/gfx/icon16/xhtml_add.png | Bin 0 -> 703 bytes .../gfx/icon16/xhtml_delete.png | Bin 0 -> 696 bytes base/resources.pk3dir/gfx/icon16/xhtml_go.png | Bin 0 -> 697 bytes .../gfx/icon16/xhtml_valid.png | Bin 0 -> 718 bytes base/resources.pk3dir/gfx/icon16/zoom.png | Bin 0 -> 692 bytes base/resources.pk3dir/gfx/icon16/zoom_in.png | Bin 0 -> 725 bytes base/resources.pk3dir/gfx/icon16/zoom_out.png | Bin 0 -> 708 bytes .../models/weapons/v_bat/sluggerskin.mat | 4 +- .../weapons/v_bat/sluggerskin_bloody.mat | 4 +- .../models/weapons/v_frag/grenskin_1.mat | 4 +- .../models/weapons/v_frag/grenskin_2.mat | 4 +- .../models/weapons/v_pistol/coltskin_1.mat | 6 +- .../models/weapons/v_pistol/coltskin_2.mat | 6 +- .../models/weapons/w_bat/world_slugger.mat | 4 +- .../models/weapons/w_frag/world_frag.mat | 4 +- .../weapons/w_pistol/world_enforcer.mat | 4 +- base/resources.pk3dir/particles/fx_spark.cfg | 11 - .../particles/impact_default.cfg | 8 - base/resources.pk3dir/scripts/bots.txt | 25 + base/resources.pk3dir/scripts/propdata.txt | 74 +- .../scripts/surfaceproperties.txt | 168 - base/resources.pk3dir/scripts/ui_style.txt | 1 + .../textures/ui/avatar_missing.mat | 12 - .../textures/ui/icons/cancel.mat | 9 - .../textures/ui/icons/cancel.tga | Bin 837 -> 0 bytes .../resources.pk3dir/textures/ui/icons/cd.mat | 9 - .../resources.pk3dir/textures/ui/icons/cd.tga | Bin 851 -> 0 bytes .../textures/ui/icons/console.mat | 9 - .../textures/ui/icons/console.tga | Bin 762 -> 0 bytes .../textures/ui/icons/desktop.mat | 9 - .../textures/ui/icons/desktop.tga | Bin 1042 -> 0 bytes .../textures/ui/icons/disconnect.mat | 9 - .../textures/ui/icons/disconnect.tga | Bin 1042 -> 0 bytes .../textures/ui/icons/encrypted.mat | 9 - .../textures/ui/icons/encrypted.tga | Bin 1042 -> 0 bytes .../textures/ui/icons/exec.mat | 9 - .../textures/ui/icons/exec.tga | Bin 1042 -> 0 bytes .../textures/ui/icons/exit.mat | 9 - .../textures/ui/icons/exit.tga | Bin 1042 -> 0 bytes .../textures/ui/icons/folder.mat | 9 - .../textures/ui/icons/folder.tga | Bin 1042 -> 0 bytes .../textures/ui/icons/gear.mat | 9 - .../textures/ui/icons/gear.tga | Bin 838 -> 0 bytes .../textures/ui/icons/hdd.mat | 9 - .../textures/ui/icons/hdd.tga | Bin 760 -> 0 bytes .../textures/ui/icons/help-open.mat | 9 - .../textures/ui/icons/help-open.tga | Bin 846 -> 0 bytes .../textures/ui/icons/help.mat | 9 - .../textures/ui/icons/help.tga | Bin 678 -> 0 bytes .../textures/ui/icons/important.mat | 9 - .../textures/ui/icons/important.tga | Bin 1042 -> 0 bytes .../textures/ui/icons/music.mat | 9 - .../textures/ui/icons/music.tga | Bin 1042 -> 0 bytes .../textures/ui/icons/refresh.mat | 9 - .../textures/ui/icons/refresh.tga | Bin 1042 -> 0 bytes .../textures/ui/icons/save.mat | 9 - .../textures/ui/icons/save.tga | Bin 648 -> 0 bytes .../textures/ui/icons/server-new.mat | 9 - .../textures/ui/icons/server-new.tga | Bin 1042 -> 0 bytes .../textures/ui/icons/servers.mat | 9 - .../textures/ui/icons/servers.tga | Bin 1042 -> 0 bytes .../textures/ui/icons/shred.mat | 9 - .../textures/ui/icons/shred.tga | Bin 1042 -> 0 bytes .../textures/ui/icons/socket.mat | 9 - .../textures/ui/icons/socket.tga | Bin 1042 -> 0 bytes .../textures/ui/icons/track-full.mat | 9 - .../textures/ui/icons/track-full.tga | Bin 1042 -> 0 bytes .../textures/ui/icons/trash.mat | 9 - .../textures/ui/icons/trash.tga | Bin 698 -> 0 bytes .../resources.pk3dir/textures/ui/m_bottom.mat | 12 - .../textures/ui/m_bottomleft.mat | 12 - .../textures/ui/m_bottomright.mat | 12 - base/resources.pk3dir/textures/ui/m_left.mat | 12 - .../textures/ui/m_linebottom.mat | 12 - .../textures/ui/m_linebottomleft.mat | 12 - .../textures/ui/m_linebottomright.mat | 12 - .../textures/ui/m_lineleft.mat | 12 - .../textures/ui/m_linemid.mat | 12 - .../textures/ui/m_lineright.mat | 12 - .../textures/ui/m_linetop.mat | 12 - .../textures/ui/m_linetopleft.mat | 12 - .../textures/ui/m_linetopright.mat | 12 - base/resources.pk3dir/textures/ui/m_mid.mat | 12 - base/resources.pk3dir/textures/ui/m_right.mat | 12 - base/resources.pk3dir/textures/ui/m_top.mat | 12 - .../textures/ui/m_topleft.mat | 12 - .../textures/ui/m_topright.mat | 12 - .../textures/ui/steam/icon_checked.mat | 9 - .../textures/ui/steam/icon_close.mat | 9 - .../textures/ui/steam/icon_down.mat | 9 - .../textures/ui/steam/icon_emptybox.mat | 9 - .../textures/ui/steam/icon_radiosel.mat | 9 - .../textures/ui/steam/icon_radiounsel.mat | 9 - .../textures/ui/steam/icon_resizer.mat | 9 - .../textures/ui/steam/icon_up.mat | 9 - .../textures/ui/voice_off.mat | 12 - .../resources.pk3dir/textures/ui/voice_on.mat | 12 - base/src/Makefile | 1 + base/src/client/Makefile | 1 + base/src/client/hud.qc | 56 + base/src/client/main.qc | 39 - base/src/progs.src | 2 + base/src/rules/Makefile | 6 + base/src/rules/deathmatch.qc | 69 + base/src/rules/singleplayer.qc | 84 + base/src/server/main.qc | 6 +- .../maps/test/func_chargers.bak | 137 - .../maps/test/func_chargers.prt | 40 - .../maps/test/func_chargers.srf | 164 - base/test_maps.pk3dir/maps/test/mapscript.bak | 115 - base/test_maps.pk3dir/maps/test/mapscript.prt | 121 - .../test/{mapscript.mapC => mapscript.qc} | 7 +- base/test_maps.pk3dir/maps/test/mapscript.srf | 164 - base/test_maps.pk3dir/maps/test/ui.qc | 13 + base/test_maps.pk3dir/maps/test/weapons.bak | 100 - base/test_maps.pk3dir/maps/test/weapons.srf | 44 - base/test_maps.pk3dir/models/logo.iqm | Bin 0 -> 614912 bytes src/botlib/defs.h | 93 +- src/{menu-vgui/background.qc => client/api.h} | 26 +- src/client/api.qc | 391 + src/client/api_func.h | 228 + src/client/cmd.qc | 24 +- src/client/commandmenu.qc | 157 + src/client/crosshair.h | 8 +- src/client/crosshair.qc | 57 +- src/client/defs.h | 6 +- src/client/entities.qc | 6 + src/client/entry.qc | 35 +- src/client/font.h | 4 +- src/client/font.qc | 4 +- src/client/hud.h | 13 + src/client/hud.qc | 156 + src/client/include.src | 3 + src/client/prints.qc | 4 +- src/client/sky.qc | 2 +- src/client/spawnmenu.qc | 157 + src/client/view.qc | 7 +- src/cvar_defaults.cfg | 185 + src/gs-entbase/client/func_smokevolume.qc | 33 +- src/gs-entbase/server.src | 1 + src/gs-entbase/server/env_explosion.qc | 2 +- src/gs-entbase/server/func_breakable.qc | 2 +- src/gs-entbase/server/func_door.qc | 2 +- src/gs-entbase/server/func_door_rotating.qc | 2 +- src/gs-entbase/server/func_mortar_field.qc | 2 +- src/gs-entbase/server/func_rotating.qc | 2 +- src/gs-entbase/server/func_train.qc | 4 +- src/gs-entbase/server/game_player_hurt.qc | 4 +- src/gs-entbase/server/game_player_team.qc | 6 +- src/gs-entbase/server/light.qc | 16 +- src/gs-entbase/server/point_camera.qc | 11 + src/gs-entbase/server/targ_speaker.qc | 3 +- src/gs-entbase/server/target_speaker.qc | 81 + src/gs-entbase/server/trigger_hurt.qc | 2 +- src/gs-entbase/shared.src | 1 + src/gs-entbase/shared/ambient_generic.qc | 31 +- src/gs-entbase/shared/env_beam.qc | 2 +- src/gs-entbase/shared/env_glow.qc | 1 + src/gs-entbase/shared/env_laser.qc | 2 +- src/gs-entbase/shared/env_sprite.qc | 33 +- src/gs-entbase/shared/func_ladder.qc | 14 +- src/gs-entbase/shared/func_monitor.qc | 59 +- src/gs-entbase/shared/func_tankmortar.qc | 2 +- src/gs-entbase/shared/func_useableladder.qc | 106 + src/gs-entbase/shared/phys_rope.qc | 3 +- .../shared/prop_vehicle_driveable.qc | 1748 ++-- src/gs-entbase/shared/speaker.qc | 7 +- src/menu-fn/background.qc | 94 - src/menu-fn/defs.h | 12 +- src/menu-fn/entry.qc | 29 +- src/menu-fn/includes.src | 1 - src/menu-fn/m_loadgame.qc | 31 +- src/menu-vgui/desktop.qc | 40 +- src/menu-vgui/includes.src | 3 +- src/menu-vgui/loading.qc | 16 +- src/menu-vgui/main.qc | 37 +- src/menu-vgui/ui_createserver.qc | 16 +- src/menu-vgui/ui_customgame.qc | 80 + src/menu-vgui/ui_findservers.qc | 2 +- src/menu-vgui/ui_loadgame.qc | 79 + src/menu-vgui/ui_modelviewer.qc | 42 +- src/menu-vgui/ui_musicplayer.qc | 24 +- src/menu-vgui/ui_newgame.qc | 7 +- src/menu-vgui/ui_quitgame.qc | 3 +- src/platform/background.h | 17 + src/platform/background.qc | 149 + src/platform/defs.h | 5 +- src/platform/gamelibrary.qc | 10 +- src/platform/includes.src | 3 + src/{server/mapC_math.h => platform/init.h} | 7 +- src/platform/init.qc | 15 + src/platform/maplibrary.qc | 8 +- src/platform/saves.h | 23 + src/platform/saves.qc | 44 + src/platform/servers.h | 15 + src/platform/servers.qc | 35 + src/server/NSGameRules.h | 6 + src/server/NSGameRules.qc | 40 +- src/server/api.h | 31 + src/server/api.qc | 237 + src/server/api_func.h | 218 + src/server/cmd_cl.qc | 7 +- src/server/cmd_sv.qc | 26 +- src/server/defs.h | 3 +- src/server/entry.qc | 114 +- src/server/include.src | 1 + src/server/logging.qc | 4 +- src/server/mapC.h | 306 - src/server/mapC_weapons.h | 94 - src/server/mapcycle.qc | 5 +- src/server/maptweaks.qc | 7 +- src/server/scripts.h | 4 + src/server/scripts.qc | 88 +- src/server/skill.qc | 16 +- src/server/spawn.qc | 27 + src/server/vote.qc | 22 +- src/shared/NSAttack.qc | 2 +- src/shared/NSClientPlayer.h | 48 +- src/shared/NSClientPlayer.qc | 184 +- src/shared/NSDict.h | 8 +- src/shared/NSDict.qc | 96 + src/shared/NSEntity.h | 50 +- src/shared/NSEntity.qc | 175 +- src/shared/NSIO.h | 4 + src/shared/NSIO.qc | 69 +- src/shared/NSItem.h | 4 + src/shared/NSItem.qc | 46 +- src/shared/NSMonster.h | 8 + src/shared/NSMonster.qc | 149 +- src/shared/NSNavAI.h | 5 +- src/shared/NSNavAI.qc | 61 +- src/shared/NSPhysicsEntity.qc | 185 +- src/shared/NSPointTrigger.h | 3 - src/shared/NSPointTrigger.qc | 28 +- src/shared/NSProjectile.h | 2 + src/shared/NSProjectile.qc | 54 +- src/shared/NSRagdoll.h | 44 + src/shared/NSRagdoll.qc | 273 + src/shared/NSRenderableEntity.qc | 20 +- src/shared/NSSound.h | 93 +- src/shared/NSSound.qc | 215 + src/shared/NSSpawnPoint.h | 5 - src/shared/NSSpawnPoint.qc | 32 +- src/shared/NSSurfacePropEntity.h | 3 - src/shared/NSSurfacePropEntity.qc | 128 +- src/shared/NSTalkMonster.h | 4 +- src/shared/NSTalkMonster.qc | 53 +- src/shared/NSWeapon.h | 76 +- src/shared/NSWeapon.qc | 208 +- src/shared/ammo.qc | 17 +- src/shared/api.h | 505 ++ src/shared/api.qc | 922 ++ src/shared/cloader.qc | 42 +- src/shared/decalgroups.qc | 20 +- src/shared/defs.h | 49 +- src/shared/entities.h | 2 + src/shared/entityDef.h | 19 +- src/shared/entityDef.qc | 38 +- src/shared/fteextensions.qc | 7680 ++++++++--------- src/shared/global.h | 19 + src/shared/include.src | 3 + src/shared/input.h | 18 + src/shared/materials.qc | 86 +- src/shared/math.h | 2 +- src/shared/player_pmove.qc | 64 +- src/shared/pmove.h | 5 +- src/shared/pmove.qc | 201 +- src/shared/pmove_custom.qc | 11 +- src/shared/propdata.qc | 96 +- src/shared/sentences.qc | 5 +- src/shared/surfaceproperties.qc | 135 +- src/shared/teams.h | 8 + src/vgui/include.src | 4 + src/vgui/ui.qc | 77 +- src/vgui/ui_button.qc | 71 +- src/vgui/ui_checkbox.qc | 22 +- src/vgui/ui_commandbutton.qc | 119 + src/vgui/ui_console.qc | 82 + src/vgui/ui_frame.qc | 7 - src/vgui/ui_label.qc | 20 +- src/vgui/ui_list.qc | 10 +- src/vgui/ui_listbox.qc | 4 +- src/vgui/ui_loadingpanel.qc | 80 + src/vgui/ui_menubutton.qc | 111 +- src/vgui/ui_progressbar.qc | 51 + src/vgui/ui_radio.qc | 22 +- src/vgui/ui_scrollbar.qc | 395 +- src/vgui/ui_textbox.qc | 14 +- src/vgui/ui_theme.qc | 180 +- src/vgui/ui_window.qc | 60 +- 1548 files changed, 12826 insertions(+), 9148 deletions(-) create mode 100644 Documentation/About.md delete mode 100644 Documentation/Decl.md create mode 100644 Documentation/DoxygenLayout.xml create mode 100644 Documentation/Footer.html create mode 100644 Documentation/GettingStarted.md create mode 100644 Documentation/footer.html create mode 100644 base/resources.pk3dir/fonts/centerprint.font create mode 100644 base/resources.pk3dir/gfx/flags16/CREDITS create mode 100755 base/resources.pk3dir/gfx/flags16/ad.png create mode 100755 base/resources.pk3dir/gfx/flags16/ae.png create mode 100755 base/resources.pk3dir/gfx/flags16/af.png create mode 100755 base/resources.pk3dir/gfx/flags16/ag.png create mode 100755 base/resources.pk3dir/gfx/flags16/ai.png create mode 100755 base/resources.pk3dir/gfx/flags16/al.png create mode 100755 base/resources.pk3dir/gfx/flags16/am.png create mode 100755 base/resources.pk3dir/gfx/flags16/an.png create mode 100644 base/resources.pk3dir/gfx/flags16/ao.png create mode 100755 base/resources.pk3dir/gfx/flags16/ar.png create mode 100755 base/resources.pk3dir/gfx/flags16/as.png create mode 100755 base/resources.pk3dir/gfx/flags16/at.png create mode 100755 base/resources.pk3dir/gfx/flags16/au.png create mode 100755 base/resources.pk3dir/gfx/flags16/aw.png create mode 100755 base/resources.pk3dir/gfx/flags16/ax.png create mode 100755 base/resources.pk3dir/gfx/flags16/az.png create mode 100755 base/resources.pk3dir/gfx/flags16/ba.png create mode 100755 base/resources.pk3dir/gfx/flags16/bb.png create mode 100755 base/resources.pk3dir/gfx/flags16/bd.png create mode 100755 base/resources.pk3dir/gfx/flags16/be.png create mode 100755 base/resources.pk3dir/gfx/flags16/bf.png create mode 100755 base/resources.pk3dir/gfx/flags16/bg.png create mode 100755 base/resources.pk3dir/gfx/flags16/bh.png create mode 100755 base/resources.pk3dir/gfx/flags16/bi.png create mode 100755 base/resources.pk3dir/gfx/flags16/bj.png create mode 100755 base/resources.pk3dir/gfx/flags16/bm.png create mode 100755 base/resources.pk3dir/gfx/flags16/bn.png create mode 100755 base/resources.pk3dir/gfx/flags16/bo.png create mode 100755 base/resources.pk3dir/gfx/flags16/br.png create mode 100755 base/resources.pk3dir/gfx/flags16/bs.png create mode 100755 base/resources.pk3dir/gfx/flags16/bt.png create mode 100755 base/resources.pk3dir/gfx/flags16/bv.png create mode 100755 base/resources.pk3dir/gfx/flags16/bw.png create mode 100755 base/resources.pk3dir/gfx/flags16/by.png create mode 100755 base/resources.pk3dir/gfx/flags16/bz.png create mode 100755 base/resources.pk3dir/gfx/flags16/ca.png create mode 100644 base/resources.pk3dir/gfx/flags16/catalonia.png create mode 100755 base/resources.pk3dir/gfx/flags16/cc.png create mode 100644 base/resources.pk3dir/gfx/flags16/cd.png create mode 100755 base/resources.pk3dir/gfx/flags16/cf.png create mode 100755 base/resources.pk3dir/gfx/flags16/cg.png create mode 100755 base/resources.pk3dir/gfx/flags16/ch.png create mode 100755 base/resources.pk3dir/gfx/flags16/ci.png create mode 100755 base/resources.pk3dir/gfx/flags16/ck.png create mode 100755 base/resources.pk3dir/gfx/flags16/cl.png create mode 100755 base/resources.pk3dir/gfx/flags16/cm.png create mode 100755 base/resources.pk3dir/gfx/flags16/cn.png create mode 100755 base/resources.pk3dir/gfx/flags16/co.png create mode 100755 base/resources.pk3dir/gfx/flags16/cr.png create mode 100755 base/resources.pk3dir/gfx/flags16/cs.png create mode 100755 base/resources.pk3dir/gfx/flags16/cu.png create mode 100755 base/resources.pk3dir/gfx/flags16/cv.png create mode 100755 base/resources.pk3dir/gfx/flags16/cx.png create mode 100755 base/resources.pk3dir/gfx/flags16/cy.png create mode 100755 base/resources.pk3dir/gfx/flags16/cz.png create mode 100755 base/resources.pk3dir/gfx/flags16/de.png create mode 100755 base/resources.pk3dir/gfx/flags16/dj.png create mode 100755 base/resources.pk3dir/gfx/flags16/dk.png create mode 100755 base/resources.pk3dir/gfx/flags16/dm.png create mode 100755 base/resources.pk3dir/gfx/flags16/do.png create mode 100755 base/resources.pk3dir/gfx/flags16/dz.png create mode 100755 base/resources.pk3dir/gfx/flags16/ec.png create mode 100755 base/resources.pk3dir/gfx/flags16/ee.png create mode 100755 base/resources.pk3dir/gfx/flags16/eg.png create mode 100755 base/resources.pk3dir/gfx/flags16/eh.png create mode 100755 base/resources.pk3dir/gfx/flags16/england.png create mode 100755 base/resources.pk3dir/gfx/flags16/er.png create mode 100755 base/resources.pk3dir/gfx/flags16/es.png create mode 100755 base/resources.pk3dir/gfx/flags16/et.png create mode 100644 base/resources.pk3dir/gfx/flags16/europeanunion.png create mode 100755 base/resources.pk3dir/gfx/flags16/fam.png create mode 100755 base/resources.pk3dir/gfx/flags16/fi.png create mode 100755 base/resources.pk3dir/gfx/flags16/fj.png create mode 100755 base/resources.pk3dir/gfx/flags16/fk.png create mode 100755 base/resources.pk3dir/gfx/flags16/fm.png create mode 100755 base/resources.pk3dir/gfx/flags16/fo.png create mode 100755 base/resources.pk3dir/gfx/flags16/fr.png create mode 100755 base/resources.pk3dir/gfx/flags16/ga.png create mode 100644 base/resources.pk3dir/gfx/flags16/gb.png create mode 100755 base/resources.pk3dir/gfx/flags16/gd.png create mode 100755 base/resources.pk3dir/gfx/flags16/ge.png create mode 100755 base/resources.pk3dir/gfx/flags16/gf.png create mode 100755 base/resources.pk3dir/gfx/flags16/gh.png create mode 100755 base/resources.pk3dir/gfx/flags16/gi.png create mode 100755 base/resources.pk3dir/gfx/flags16/gl.png create mode 100755 base/resources.pk3dir/gfx/flags16/gm.png create mode 100755 base/resources.pk3dir/gfx/flags16/gn.png create mode 100755 base/resources.pk3dir/gfx/flags16/gp.png create mode 100755 base/resources.pk3dir/gfx/flags16/gq.png create mode 100755 base/resources.pk3dir/gfx/flags16/gr.png create mode 100755 base/resources.pk3dir/gfx/flags16/gs.png create mode 100755 base/resources.pk3dir/gfx/flags16/gt.png create mode 100755 base/resources.pk3dir/gfx/flags16/gu.png create mode 100755 base/resources.pk3dir/gfx/flags16/gw.png create mode 100755 base/resources.pk3dir/gfx/flags16/gy.png create mode 100755 base/resources.pk3dir/gfx/flags16/hk.png create mode 100755 base/resources.pk3dir/gfx/flags16/hm.png create mode 100755 base/resources.pk3dir/gfx/flags16/hn.png create mode 100755 base/resources.pk3dir/gfx/flags16/hr.png create mode 100755 base/resources.pk3dir/gfx/flags16/ht.png create mode 100755 base/resources.pk3dir/gfx/flags16/hu.png create mode 100755 base/resources.pk3dir/gfx/flags16/id.png create mode 100755 base/resources.pk3dir/gfx/flags16/ie.png create mode 100755 base/resources.pk3dir/gfx/flags16/il.png create mode 100755 base/resources.pk3dir/gfx/flags16/in.png create mode 100755 base/resources.pk3dir/gfx/flags16/io.png create mode 100755 base/resources.pk3dir/gfx/flags16/iq.png create mode 100755 base/resources.pk3dir/gfx/flags16/ir.png create mode 100755 base/resources.pk3dir/gfx/flags16/is.png create mode 100755 base/resources.pk3dir/gfx/flags16/it.png create mode 100755 base/resources.pk3dir/gfx/flags16/jm.png create mode 100755 base/resources.pk3dir/gfx/flags16/jo.png create mode 100755 base/resources.pk3dir/gfx/flags16/jp.png create mode 100755 base/resources.pk3dir/gfx/flags16/ke.png create mode 100755 base/resources.pk3dir/gfx/flags16/kg.png create mode 100755 base/resources.pk3dir/gfx/flags16/kh.png create mode 100755 base/resources.pk3dir/gfx/flags16/ki.png create mode 100755 base/resources.pk3dir/gfx/flags16/km.png create mode 100755 base/resources.pk3dir/gfx/flags16/kn.png create mode 100755 base/resources.pk3dir/gfx/flags16/kp.png create mode 100755 base/resources.pk3dir/gfx/flags16/kr.png create mode 100755 base/resources.pk3dir/gfx/flags16/kw.png create mode 100755 base/resources.pk3dir/gfx/flags16/ky.png create mode 100755 base/resources.pk3dir/gfx/flags16/kz.png create mode 100755 base/resources.pk3dir/gfx/flags16/la.png create mode 100755 base/resources.pk3dir/gfx/flags16/lb.png create mode 100644 base/resources.pk3dir/gfx/flags16/lc.png create mode 100755 base/resources.pk3dir/gfx/flags16/li.png create mode 100755 base/resources.pk3dir/gfx/flags16/lk.png create mode 100755 base/resources.pk3dir/gfx/flags16/lr.png create mode 100755 base/resources.pk3dir/gfx/flags16/ls.png create mode 100755 base/resources.pk3dir/gfx/flags16/lt.png create mode 100755 base/resources.pk3dir/gfx/flags16/lu.png create mode 100755 base/resources.pk3dir/gfx/flags16/lv.png create mode 100755 base/resources.pk3dir/gfx/flags16/ly.png create mode 100755 base/resources.pk3dir/gfx/flags16/ma.png create mode 100755 base/resources.pk3dir/gfx/flags16/mc.png create mode 100755 base/resources.pk3dir/gfx/flags16/md.png create mode 100644 base/resources.pk3dir/gfx/flags16/me.png create mode 100755 base/resources.pk3dir/gfx/flags16/mg.png create mode 100755 base/resources.pk3dir/gfx/flags16/mh.png create mode 100755 base/resources.pk3dir/gfx/flags16/mk.png create mode 100755 base/resources.pk3dir/gfx/flags16/ml.png create mode 100755 base/resources.pk3dir/gfx/flags16/mm.png create mode 100755 base/resources.pk3dir/gfx/flags16/mn.png create mode 100755 base/resources.pk3dir/gfx/flags16/mo.png create mode 100755 base/resources.pk3dir/gfx/flags16/mp.png create mode 100755 base/resources.pk3dir/gfx/flags16/mq.png create mode 100755 base/resources.pk3dir/gfx/flags16/mr.png create mode 100755 base/resources.pk3dir/gfx/flags16/ms.png create mode 100755 base/resources.pk3dir/gfx/flags16/mt.png create mode 100755 base/resources.pk3dir/gfx/flags16/mu.png create mode 100755 base/resources.pk3dir/gfx/flags16/mv.png create mode 100755 base/resources.pk3dir/gfx/flags16/mw.png create mode 100755 base/resources.pk3dir/gfx/flags16/mx.png create mode 100755 base/resources.pk3dir/gfx/flags16/my.png create mode 100755 base/resources.pk3dir/gfx/flags16/mz.png create mode 100755 base/resources.pk3dir/gfx/flags16/na.png create mode 100755 base/resources.pk3dir/gfx/flags16/nc.png create mode 100755 base/resources.pk3dir/gfx/flags16/ne.png create mode 100755 base/resources.pk3dir/gfx/flags16/nf.png create mode 100755 base/resources.pk3dir/gfx/flags16/ng.png create mode 100755 base/resources.pk3dir/gfx/flags16/ni.png create mode 100755 base/resources.pk3dir/gfx/flags16/nl.png create mode 100755 base/resources.pk3dir/gfx/flags16/no.png create mode 100755 base/resources.pk3dir/gfx/flags16/np.png create mode 100755 base/resources.pk3dir/gfx/flags16/nr.png create mode 100755 base/resources.pk3dir/gfx/flags16/nu.png create mode 100755 base/resources.pk3dir/gfx/flags16/nz.png create mode 100755 base/resources.pk3dir/gfx/flags16/om.png create mode 100755 base/resources.pk3dir/gfx/flags16/pa.png create mode 100755 base/resources.pk3dir/gfx/flags16/pe.png create mode 100755 base/resources.pk3dir/gfx/flags16/pf.png create mode 100755 base/resources.pk3dir/gfx/flags16/pg.png create mode 100755 base/resources.pk3dir/gfx/flags16/ph.png create mode 100755 base/resources.pk3dir/gfx/flags16/pk.png create mode 100755 base/resources.pk3dir/gfx/flags16/pl.png create mode 100755 base/resources.pk3dir/gfx/flags16/pm.png create mode 100755 base/resources.pk3dir/gfx/flags16/pn.png create mode 100755 base/resources.pk3dir/gfx/flags16/pr.png create mode 100755 base/resources.pk3dir/gfx/flags16/ps.png create mode 100755 base/resources.pk3dir/gfx/flags16/pt.png create mode 100755 base/resources.pk3dir/gfx/flags16/pw.png create mode 100755 base/resources.pk3dir/gfx/flags16/py.png create mode 100755 base/resources.pk3dir/gfx/flags16/qa.png create mode 100755 base/resources.pk3dir/gfx/flags16/re.png create mode 100755 base/resources.pk3dir/gfx/flags16/ro.png create mode 100644 base/resources.pk3dir/gfx/flags16/rs.png create mode 100755 base/resources.pk3dir/gfx/flags16/ru.png create mode 100755 base/resources.pk3dir/gfx/flags16/rw.png create mode 100755 base/resources.pk3dir/gfx/flags16/sa.png create mode 100755 base/resources.pk3dir/gfx/flags16/sb.png create mode 100755 base/resources.pk3dir/gfx/flags16/sc.png create mode 100755 base/resources.pk3dir/gfx/flags16/scotland.png create mode 100755 base/resources.pk3dir/gfx/flags16/sd.png create mode 100755 base/resources.pk3dir/gfx/flags16/se.png create mode 100755 base/resources.pk3dir/gfx/flags16/sg.png create mode 100755 base/resources.pk3dir/gfx/flags16/sh.png create mode 100755 base/resources.pk3dir/gfx/flags16/si.png create mode 100755 base/resources.pk3dir/gfx/flags16/sj.png create mode 100755 base/resources.pk3dir/gfx/flags16/sk.png create mode 100755 base/resources.pk3dir/gfx/flags16/sl.png create mode 100755 base/resources.pk3dir/gfx/flags16/sm.png create mode 100755 base/resources.pk3dir/gfx/flags16/sn.png create mode 100755 base/resources.pk3dir/gfx/flags16/so.png create mode 100755 base/resources.pk3dir/gfx/flags16/sr.png create mode 100755 base/resources.pk3dir/gfx/flags16/st.png create mode 100755 base/resources.pk3dir/gfx/flags16/sv.png create mode 100755 base/resources.pk3dir/gfx/flags16/sy.png create mode 100755 base/resources.pk3dir/gfx/flags16/sz.png create mode 100755 base/resources.pk3dir/gfx/flags16/tc.png create mode 100755 base/resources.pk3dir/gfx/flags16/td.png create mode 100755 base/resources.pk3dir/gfx/flags16/tf.png create mode 100755 base/resources.pk3dir/gfx/flags16/tg.png create mode 100755 base/resources.pk3dir/gfx/flags16/th.png create mode 100755 base/resources.pk3dir/gfx/flags16/tj.png create mode 100755 base/resources.pk3dir/gfx/flags16/tk.png create mode 100755 base/resources.pk3dir/gfx/flags16/tl.png create mode 100755 base/resources.pk3dir/gfx/flags16/tm.png create mode 100755 base/resources.pk3dir/gfx/flags16/tn.png create mode 100755 base/resources.pk3dir/gfx/flags16/to.png create mode 100755 base/resources.pk3dir/gfx/flags16/tr.png create mode 100755 base/resources.pk3dir/gfx/flags16/tt.png create mode 100755 base/resources.pk3dir/gfx/flags16/tv.png create mode 100755 base/resources.pk3dir/gfx/flags16/tw.png create mode 100755 base/resources.pk3dir/gfx/flags16/tz.png create mode 100755 base/resources.pk3dir/gfx/flags16/ua.png create mode 100755 base/resources.pk3dir/gfx/flags16/ug.png create mode 100755 base/resources.pk3dir/gfx/flags16/um.png create mode 100755 base/resources.pk3dir/gfx/flags16/us.png create mode 100755 base/resources.pk3dir/gfx/flags16/uy.png create mode 100755 base/resources.pk3dir/gfx/flags16/uz.png create mode 100755 base/resources.pk3dir/gfx/flags16/va.png create mode 100755 base/resources.pk3dir/gfx/flags16/vc.png create mode 100755 base/resources.pk3dir/gfx/flags16/ve.png create mode 100755 base/resources.pk3dir/gfx/flags16/vg.png create mode 100755 base/resources.pk3dir/gfx/flags16/vi.png create mode 100755 base/resources.pk3dir/gfx/flags16/vn.png create mode 100755 base/resources.pk3dir/gfx/flags16/vu.png create mode 100755 base/resources.pk3dir/gfx/flags16/wales.png create mode 100755 base/resources.pk3dir/gfx/flags16/wf.png create mode 100755 base/resources.pk3dir/gfx/flags16/ws.png create mode 100755 base/resources.pk3dir/gfx/flags16/ye.png create mode 100755 base/resources.pk3dir/gfx/flags16/yt.png create mode 100755 base/resources.pk3dir/gfx/flags16/za.png create mode 100755 base/resources.pk3dir/gfx/flags16/zm.png create mode 100755 base/resources.pk3dir/gfx/flags16/zw.png create mode 100644 base/resources.pk3dir/gfx/icon16/CREDITS create mode 100644 base/resources.pk3dir/gfx/icon16/accept.png create mode 100644 base/resources.pk3dir/gfx/icon16/add.png create mode 100644 base/resources.pk3dir/gfx/icon16/anchor.png create mode 100644 base/resources.pk3dir/gfx/icon16/application.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_cascade.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_double.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_form.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_form_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_form_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_form_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_form_magnify.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_get.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_home.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_lightning.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_osx.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_osx_terminal.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_put.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_side_boxes.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_side_contract.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_side_expand.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_side_list.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_side_tree.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_split.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_tile_horizontal.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_tile_vertical.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_view_columns.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_view_detail.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_view_gallery.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_view_icons.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_view_list.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_view_tile.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_xp.png create mode 100644 base/resources.pk3dir/gfx/icon16/application_xp_terminal.png create mode 100644 base/resources.pk3dir/gfx/icon16/arrow_branch.png create mode 100644 base/resources.pk3dir/gfx/icon16/arrow_divide.png create mode 100644 base/resources.pk3dir/gfx/icon16/arrow_down.png create mode 100644 base/resources.pk3dir/gfx/icon16/arrow_in.png create mode 100644 base/resources.pk3dir/gfx/icon16/arrow_inout.png create mode 100644 base/resources.pk3dir/gfx/icon16/arrow_join.png create mode 100644 base/resources.pk3dir/gfx/icon16/arrow_left.png create mode 100644 base/resources.pk3dir/gfx/icon16/arrow_merge.png create mode 100644 base/resources.pk3dir/gfx/icon16/arrow_out.png create mode 100644 base/resources.pk3dir/gfx/icon16/arrow_redo.png create mode 100644 base/resources.pk3dir/gfx/icon16/arrow_refresh.png create mode 100644 base/resources.pk3dir/gfx/icon16/arrow_refresh_small.png create mode 100644 base/resources.pk3dir/gfx/icon16/arrow_right.png create mode 100644 base/resources.pk3dir/gfx/icon16/arrow_rotate_anticlockwise.png create mode 100644 base/resources.pk3dir/gfx/icon16/arrow_rotate_clockwise.png create mode 100644 base/resources.pk3dir/gfx/icon16/arrow_switch.png create mode 100644 base/resources.pk3dir/gfx/icon16/arrow_turn_left.png create mode 100644 base/resources.pk3dir/gfx/icon16/arrow_turn_right.png create mode 100644 base/resources.pk3dir/gfx/icon16/arrow_undo.png create mode 100644 base/resources.pk3dir/gfx/icon16/arrow_up.png create mode 100644 base/resources.pk3dir/gfx/icon16/asterisk_orange.png create mode 100644 base/resources.pk3dir/gfx/icon16/asterisk_yellow.png create mode 100644 base/resources.pk3dir/gfx/icon16/attach.png create mode 100644 base/resources.pk3dir/gfx/icon16/award_star_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/award_star_bronze_1.png create mode 100644 base/resources.pk3dir/gfx/icon16/award_star_bronze_2.png create mode 100644 base/resources.pk3dir/gfx/icon16/award_star_bronze_3.png create mode 100644 base/resources.pk3dir/gfx/icon16/award_star_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/award_star_gold_1.png create mode 100644 base/resources.pk3dir/gfx/icon16/award_star_gold_2.png create mode 100644 base/resources.pk3dir/gfx/icon16/award_star_gold_3.png create mode 100644 base/resources.pk3dir/gfx/icon16/award_star_silver_1.png create mode 100644 base/resources.pk3dir/gfx/icon16/award_star_silver_2.png create mode 100644 base/resources.pk3dir/gfx/icon16/award_star_silver_3.png create mode 100644 base/resources.pk3dir/gfx/icon16/basket.png create mode 100644 base/resources.pk3dir/gfx/icon16/basket_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/basket_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/basket_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/basket_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/basket_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/basket_put.png create mode 100644 base/resources.pk3dir/gfx/icon16/basket_remove.png create mode 100644 base/resources.pk3dir/gfx/icon16/bell.png create mode 100644 base/resources.pk3dir/gfx/icon16/bell_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/bell_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/bell_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/bell_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/bell_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/bin.png create mode 100644 base/resources.pk3dir/gfx/icon16/bin_closed.png create mode 100644 base/resources.pk3dir/gfx/icon16/bin_empty.png create mode 100644 base/resources.pk3dir/gfx/icon16/bomb.png create mode 100644 base/resources.pk3dir/gfx/icon16/book.png create mode 100644 base/resources.pk3dir/gfx/icon16/book_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/book_addresses.png create mode 100644 base/resources.pk3dir/gfx/icon16/book_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/book_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/book_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/book_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/book_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/book_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/book_next.png create mode 100644 base/resources.pk3dir/gfx/icon16/book_open.png create mode 100644 base/resources.pk3dir/gfx/icon16/book_previous.png create mode 100644 base/resources.pk3dir/gfx/icon16/box.png create mode 100644 base/resources.pk3dir/gfx/icon16/brick.png create mode 100644 base/resources.pk3dir/gfx/icon16/brick_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/brick_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/brick_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/brick_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/brick_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/brick_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/bricks.png create mode 100644 base/resources.pk3dir/gfx/icon16/briefcase.png create mode 100644 base/resources.pk3dir/gfx/icon16/bug.png create mode 100644 base/resources.pk3dir/gfx/icon16/bug_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/bug_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/bug_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/bug_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/bug_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/bug_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/building.png create mode 100644 base/resources.pk3dir/gfx/icon16/building_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/building_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/building_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/building_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/building_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/building_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/building_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_arrow_bottom.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_arrow_down.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_arrow_top.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_arrow_up.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_black.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_blue.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_disk.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_feed.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_green.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_orange.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_picture.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_pink.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_purple.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_red.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_star.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_toggle_minus.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_toggle_plus.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_white.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_wrench.png create mode 100644 base/resources.pk3dir/gfx/icon16/bullet_yellow.png create mode 100644 base/resources.pk3dir/gfx/icon16/cake.png create mode 100644 base/resources.pk3dir/gfx/icon16/calculator.png create mode 100644 base/resources.pk3dir/gfx/icon16/calculator_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/calculator_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/calculator_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/calculator_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/calculator_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/calendar.png create mode 100644 base/resources.pk3dir/gfx/icon16/calendar_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/calendar_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/calendar_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/calendar_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/calendar_view_day.png create mode 100644 base/resources.pk3dir/gfx/icon16/calendar_view_month.png create mode 100644 base/resources.pk3dir/gfx/icon16/calendar_view_week.png create mode 100644 base/resources.pk3dir/gfx/icon16/camera.png create mode 100644 base/resources.pk3dir/gfx/icon16/camera_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/camera_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/camera_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/camera_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/camera_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/camera_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/camera_small.png create mode 100644 base/resources.pk3dir/gfx/icon16/cancel.png create mode 100644 base/resources.pk3dir/gfx/icon16/car.png create mode 100644 base/resources.pk3dir/gfx/icon16/car_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/car_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/cart.png create mode 100644 base/resources.pk3dir/gfx/icon16/cart_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/cart_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/cart_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/cart_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/cart_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/cart_put.png create mode 100644 base/resources.pk3dir/gfx/icon16/cart_remove.png create mode 100644 base/resources.pk3dir/gfx/icon16/cd.png create mode 100644 base/resources.pk3dir/gfx/icon16/cd_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/cd_burn.png create mode 100644 base/resources.pk3dir/gfx/icon16/cd_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/cd_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/cd_eject.png create mode 100644 base/resources.pk3dir/gfx/icon16/cd_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_bar.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_bar_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_bar_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_bar_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_bar_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_bar_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_curve.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_curve_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_curve_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_curve_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_curve_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_curve_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_curve_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_line.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_line_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_line_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_line_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_line_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_line_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_organisation.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_organisation_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_organisation_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_pie.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_pie_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_pie_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_pie_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_pie_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/chart_pie_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/clock.png create mode 100644 base/resources.pk3dir/gfx/icon16/clock_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/clock_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/clock_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/clock_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/clock_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/clock_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/clock_pause.png create mode 100644 base/resources.pk3dir/gfx/icon16/clock_play.png create mode 100644 base/resources.pk3dir/gfx/icon16/clock_red.png create mode 100644 base/resources.pk3dir/gfx/icon16/clock_stop.png create mode 100644 base/resources.pk3dir/gfx/icon16/cog.png create mode 100644 base/resources.pk3dir/gfx/icon16/cog_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/cog_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/cog_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/cog_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/cog_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/coins.png create mode 100644 base/resources.pk3dir/gfx/icon16/coins_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/coins_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/color_swatch.png create mode 100644 base/resources.pk3dir/gfx/icon16/color_wheel.png create mode 100644 base/resources.pk3dir/gfx/icon16/comment.png create mode 100644 base/resources.pk3dir/gfx/icon16/comment_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/comment_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/comment_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/comments.png create mode 100644 base/resources.pk3dir/gfx/icon16/comments_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/comments_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/compress.png create mode 100644 base/resources.pk3dir/gfx/icon16/computer.png create mode 100644 base/resources.pk3dir/gfx/icon16/computer_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/computer_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/computer_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/computer_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/computer_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/computer_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/computer_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/connect.png create mode 100644 base/resources.pk3dir/gfx/icon16/contrast.png create mode 100644 base/resources.pk3dir/gfx/icon16/contrast_decrease.png create mode 100644 base/resources.pk3dir/gfx/icon16/contrast_high.png create mode 100644 base/resources.pk3dir/gfx/icon16/contrast_increase.png create mode 100644 base/resources.pk3dir/gfx/icon16/contrast_low.png create mode 100644 base/resources.pk3dir/gfx/icon16/control_eject.png create mode 100644 base/resources.pk3dir/gfx/icon16/control_eject_blue.png create mode 100644 base/resources.pk3dir/gfx/icon16/control_end.png create mode 100644 base/resources.pk3dir/gfx/icon16/control_end_blue.png create mode 100644 base/resources.pk3dir/gfx/icon16/control_equalizer.png create mode 100644 base/resources.pk3dir/gfx/icon16/control_equalizer_blue.png create mode 100644 base/resources.pk3dir/gfx/icon16/control_fastforward.png create mode 100644 base/resources.pk3dir/gfx/icon16/control_fastforward_blue.png create mode 100644 base/resources.pk3dir/gfx/icon16/control_pause.png create mode 100644 base/resources.pk3dir/gfx/icon16/control_pause_blue.png create mode 100644 base/resources.pk3dir/gfx/icon16/control_play.png create mode 100644 base/resources.pk3dir/gfx/icon16/control_play_blue.png create mode 100644 base/resources.pk3dir/gfx/icon16/control_repeat.png create mode 100644 base/resources.pk3dir/gfx/icon16/control_repeat_blue.png create mode 100644 base/resources.pk3dir/gfx/icon16/control_rewind.png create mode 100644 base/resources.pk3dir/gfx/icon16/control_rewind_blue.png create mode 100644 base/resources.pk3dir/gfx/icon16/control_start.png create mode 100644 base/resources.pk3dir/gfx/icon16/control_start_blue.png create mode 100644 base/resources.pk3dir/gfx/icon16/control_stop.png create mode 100644 base/resources.pk3dir/gfx/icon16/control_stop_blue.png create mode 100644 base/resources.pk3dir/gfx/icon16/controller.png create mode 100644 base/resources.pk3dir/gfx/icon16/controller_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/controller_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/controller_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/creditcards.png create mode 100644 base/resources.pk3dir/gfx/icon16/cross.png create mode 100644 base/resources.pk3dir/gfx/icon16/cross_mono.png create mode 100644 base/resources.pk3dir/gfx/icon16/css.png create mode 100644 base/resources.pk3dir/gfx/icon16/css_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/css_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/css_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/css_valid.png create mode 100644 base/resources.pk3dir/gfx/icon16/cup.png create mode 100644 base/resources.pk3dir/gfx/icon16/cup_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/cup_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/cup_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/cup_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/cup_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/cup_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/cup_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/cursor.png create mode 100644 base/resources.pk3dir/gfx/icon16/cut.png create mode 100644 base/resources.pk3dir/gfx/icon16/cut_red.png create mode 100644 base/resources.pk3dir/gfx/icon16/database.png create mode 100644 base/resources.pk3dir/gfx/icon16/database_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/database_connect.png create mode 100644 base/resources.pk3dir/gfx/icon16/database_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/database_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/database_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/database_gear.png create mode 100644 base/resources.pk3dir/gfx/icon16/database_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/database_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/database_lightning.png create mode 100644 base/resources.pk3dir/gfx/icon16/database_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/database_refresh.png create mode 100644 base/resources.pk3dir/gfx/icon16/database_save.png create mode 100644 base/resources.pk3dir/gfx/icon16/database_table.png create mode 100644 base/resources.pk3dir/gfx/icon16/date.png create mode 100644 base/resources.pk3dir/gfx/icon16/date_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/date_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/date_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/date_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/date_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/date_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/date_magnify.png create mode 100644 base/resources.pk3dir/gfx/icon16/date_next.png create mode 100644 base/resources.pk3dir/gfx/icon16/date_previous.png create mode 100644 base/resources.pk3dir/gfx/icon16/delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/disconnect.png create mode 100644 base/resources.pk3dir/gfx/icon16/disk.png create mode 100644 base/resources.pk3dir/gfx/icon16/disk_multiple.png create mode 100644 base/resources.pk3dir/gfx/icon16/door.png create mode 100644 base/resources.pk3dir/gfx/icon16/door_in.png create mode 100644 base/resources.pk3dir/gfx/icon16/door_open.png create mode 100644 base/resources.pk3dir/gfx/icon16/door_out.png create mode 100644 base/resources.pk3dir/gfx/icon16/drink.png create mode 100644 base/resources.pk3dir/gfx/icon16/drink_empty.png create mode 100644 base/resources.pk3dir/gfx/icon16/drive.png create mode 100644 base/resources.pk3dir/gfx/icon16/drive_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/drive_burn.png create mode 100644 base/resources.pk3dir/gfx/icon16/drive_cd.png create mode 100644 base/resources.pk3dir/gfx/icon16/drive_cd_empty.png create mode 100644 base/resources.pk3dir/gfx/icon16/drive_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/drive_disk.png create mode 100644 base/resources.pk3dir/gfx/icon16/drive_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/drive_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/drive_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/drive_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/drive_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/drive_magnify.png create mode 100644 base/resources.pk3dir/gfx/icon16/drive_network.png create mode 100644 base/resources.pk3dir/gfx/icon16/drive_rename.png create mode 100644 base/resources.pk3dir/gfx/icon16/drive_user.png create mode 100644 base/resources.pk3dir/gfx/icon16/drive_web.png create mode 100644 base/resources.pk3dir/gfx/icon16/dvd.png create mode 100644 base/resources.pk3dir/gfx/icon16/dvd_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/dvd_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/dvd_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/dvd_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/dvd_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/dvd_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/dvd_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/email.png create mode 100644 base/resources.pk3dir/gfx/icon16/email_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/email_attach.png create mode 100644 base/resources.pk3dir/gfx/icon16/email_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/email_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/email_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/email_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/email_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/email_open.png create mode 100644 base/resources.pk3dir/gfx/icon16/email_open_image.png create mode 100644 base/resources.pk3dir/gfx/icon16/emoticon_evilgrin.png create mode 100644 base/resources.pk3dir/gfx/icon16/emoticon_grin.png create mode 100644 base/resources.pk3dir/gfx/icon16/emoticon_happy.png create mode 100644 base/resources.pk3dir/gfx/icon16/emoticon_smile.png create mode 100644 base/resources.pk3dir/gfx/icon16/emoticon_surprised.png create mode 100644 base/resources.pk3dir/gfx/icon16/emoticon_tongue.png create mode 100644 base/resources.pk3dir/gfx/icon16/emoticon_unhappy.png create mode 100644 base/resources.pk3dir/gfx/icon16/emoticon_waii.png create mode 100644 base/resources.pk3dir/gfx/icon16/emoticon_wink.png create mode 100644 base/resources.pk3dir/gfx/icon16/error.png create mode 100644 base/resources.pk3dir/gfx/icon16/error_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/error_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/error_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/exclamation.png create mode 100644 base/resources.pk3dir/gfx/icon16/eye.png create mode 100644 base/resources.pk3dir/gfx/icon16/feed.png create mode 100644 base/resources.pk3dir/gfx/icon16/feed_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/feed_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/feed_disk.png create mode 100644 base/resources.pk3dir/gfx/icon16/feed_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/feed_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/feed_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/feed_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/feed_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/feed_magnify.png create mode 100644 base/resources.pk3dir/gfx/icon16/female.png create mode 100644 base/resources.pk3dir/gfx/icon16/film.png create mode 100644 base/resources.pk3dir/gfx/icon16/film_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/film_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/film_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/film_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/film_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/film_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/film_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/film_save.png create mode 100644 base/resources.pk3dir/gfx/icon16/find.png create mode 100644 base/resources.pk3dir/gfx/icon16/flag_blue.png create mode 100644 base/resources.pk3dir/gfx/icon16/flag_green.png create mode 100644 base/resources.pk3dir/gfx/icon16/flag_orange.png create mode 100644 base/resources.pk3dir/gfx/icon16/flag_pink.png create mode 100644 base/resources.pk3dir/gfx/icon16/flag_purple.png create mode 100644 base/resources.pk3dir/gfx/icon16/flag_red.png create mode 100644 base/resources.pk3dir/gfx/icon16/flag_yellow.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_bell.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_brick.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_bug.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_camera.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_database.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_explore.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_feed.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_find.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_heart.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_image.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_lightbulb.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_magnify.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_page.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_page_white.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_palette.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_picture.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_star.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_table.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_user.png create mode 100644 base/resources.pk3dir/gfx/icon16/folder_wrench.png create mode 100644 base/resources.pk3dir/gfx/icon16/font.png create mode 100644 base/resources.pk3dir/gfx/icon16/font_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/font_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/font_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/group.png create mode 100644 base/resources.pk3dir/gfx/icon16/group_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/group_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/group_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/group_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/group_gear.png create mode 100644 base/resources.pk3dir/gfx/icon16/group_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/group_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/group_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/heart.png create mode 100644 base/resources.pk3dir/gfx/icon16/heart_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/heart_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/help.png create mode 100644 base/resources.pk3dir/gfx/icon16/hourglass.png create mode 100644 base/resources.pk3dir/gfx/icon16/hourglass_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/hourglass_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/hourglass_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/hourglass_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/house.png create mode 100644 base/resources.pk3dir/gfx/icon16/house_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/house_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/html.png create mode 100644 base/resources.pk3dir/gfx/icon16/html_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/html_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/html_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/html_valid.png create mode 100644 base/resources.pk3dir/gfx/icon16/image.png create mode 100644 base/resources.pk3dir/gfx/icon16/image_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/image_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/image_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/image_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/images.png create mode 100644 base/resources.pk3dir/gfx/icon16/information.png create mode 100644 base/resources.pk3dir/gfx/icon16/ipod.png create mode 100644 base/resources.pk3dir/gfx/icon16/ipod_cast.png create mode 100644 base/resources.pk3dir/gfx/icon16/ipod_cast_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/ipod_cast_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/ipod_sound.png create mode 100644 base/resources.pk3dir/gfx/icon16/joystick.png create mode 100644 base/resources.pk3dir/gfx/icon16/joystick_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/joystick_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/joystick_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/key.png create mode 100644 base/resources.pk3dir/gfx/icon16/key_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/key_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/key_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/keyboard.png create mode 100644 base/resources.pk3dir/gfx/icon16/keyboard_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/keyboard_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/keyboard_magnify.png create mode 100644 base/resources.pk3dir/gfx/icon16/layers.png create mode 100644 base/resources.pk3dir/gfx/icon16/layout.png create mode 100644 base/resources.pk3dir/gfx/icon16/layout_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/layout_content.png create mode 100644 base/resources.pk3dir/gfx/icon16/layout_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/layout_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/layout_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/layout_header.png create mode 100644 base/resources.pk3dir/gfx/icon16/layout_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/layout_sidebar.png create mode 100644 base/resources.pk3dir/gfx/icon16/lightbulb.png create mode 100644 base/resources.pk3dir/gfx/icon16/lightbulb_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/lightbulb_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/lightbulb_off.png create mode 100644 base/resources.pk3dir/gfx/icon16/lightning.png create mode 100644 base/resources.pk3dir/gfx/icon16/lightning_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/lightning_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/lightning_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/link.png create mode 100644 base/resources.pk3dir/gfx/icon16/link_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/link_break.png create mode 100644 base/resources.pk3dir/gfx/icon16/link_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/link_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/link_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/link_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/lock.png create mode 100644 base/resources.pk3dir/gfx/icon16/lock_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/lock_break.png create mode 100644 base/resources.pk3dir/gfx/icon16/lock_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/lock_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/lock_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/lock_open.png create mode 100644 base/resources.pk3dir/gfx/icon16/lorry.png create mode 100644 base/resources.pk3dir/gfx/icon16/lorry_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/lorry_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/lorry_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/lorry_flatbed.png create mode 100644 base/resources.pk3dir/gfx/icon16/lorry_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/lorry_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/magnifier.png create mode 100644 base/resources.pk3dir/gfx/icon16/magnifier_zoom_in.png create mode 100644 base/resources.pk3dir/gfx/icon16/magnifier_zoom_out.png create mode 100644 base/resources.pk3dir/gfx/icon16/male.png create mode 100644 base/resources.pk3dir/gfx/icon16/map.png create mode 100644 base/resources.pk3dir/gfx/icon16/map_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/map_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/map_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/map_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/map_magnify.png create mode 100644 base/resources.pk3dir/gfx/icon16/medal_bronze_1.png create mode 100644 base/resources.pk3dir/gfx/icon16/medal_bronze_2.png create mode 100644 base/resources.pk3dir/gfx/icon16/medal_bronze_3.png create mode 100644 base/resources.pk3dir/gfx/icon16/medal_bronze_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/medal_bronze_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/medal_gold_1.png create mode 100644 base/resources.pk3dir/gfx/icon16/medal_gold_2.png create mode 100644 base/resources.pk3dir/gfx/icon16/medal_gold_3.png create mode 100644 base/resources.pk3dir/gfx/icon16/medal_gold_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/medal_gold_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/medal_silver_1.png create mode 100644 base/resources.pk3dir/gfx/icon16/medal_silver_2.png create mode 100644 base/resources.pk3dir/gfx/icon16/medal_silver_3.png create mode 100644 base/resources.pk3dir/gfx/icon16/medal_silver_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/medal_silver_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/money.png create mode 100644 base/resources.pk3dir/gfx/icon16/money_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/money_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/money_dollar.png create mode 100644 base/resources.pk3dir/gfx/icon16/money_euro.png create mode 100644 base/resources.pk3dir/gfx/icon16/money_pound.png create mode 100644 base/resources.pk3dir/gfx/icon16/money_yen.png create mode 100644 base/resources.pk3dir/gfx/icon16/monitor.png create mode 100644 base/resources.pk3dir/gfx/icon16/monitor_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/monitor_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/monitor_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/monitor_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/monitor_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/monitor_lightning.png create mode 100644 base/resources.pk3dir/gfx/icon16/monitor_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/mouse.png create mode 100644 base/resources.pk3dir/gfx/icon16/mouse_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/mouse_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/mouse_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/music.png create mode 100644 base/resources.pk3dir/gfx/icon16/new.png create mode 100644 base/resources.pk3dir/gfx/icon16/newspaper.png create mode 100644 base/resources.pk3dir/gfx/icon16/newspaper_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/newspaper_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/newspaper_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/newspaper_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/note.png create mode 100644 base/resources.pk3dir/gfx/icon16/note_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/note_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/note_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/note_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/note_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/package.png create mode 100644 base/resources.pk3dir/gfx/icon16/package_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/package_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/package_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/package_green.png create mode 100644 base/resources.pk3dir/gfx/icon16/package_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/page.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_attach.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_code.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_copy.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_excel.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_find.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_gear.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_green.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_lightning.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_paintbrush.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_paste.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_red.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_refresh.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_save.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_acrobat.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_actionscript.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_c.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_camera.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_cd.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_code.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_code_red.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_coldfusion.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_compressed.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_copy.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_cplusplus.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_csharp.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_cup.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_database.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_dvd.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_excel.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_find.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_flash.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_freehand.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_gear.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_get.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_h.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_horizontal.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_lightning.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_magnify.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_medal.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_office.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_paint.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_paintbrush.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_paste.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_php.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_picture.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_powerpoint.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_put.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_ruby.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_stack.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_star.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_swoosh.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_text.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_text_width.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_tux.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_vector.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_visualstudio.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_width.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_word.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_world.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_wrench.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_white_zip.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_word.png create mode 100644 base/resources.pk3dir/gfx/icon16/page_world.png create mode 100644 base/resources.pk3dir/gfx/icon16/paintbrush.png create mode 100644 base/resources.pk3dir/gfx/icon16/paintcan.png create mode 100644 base/resources.pk3dir/gfx/icon16/palette.png create mode 100644 base/resources.pk3dir/gfx/icon16/paste_plain.png create mode 100644 base/resources.pk3dir/gfx/icon16/paste_word.png create mode 100644 base/resources.pk3dir/gfx/icon16/pencil.png create mode 100644 base/resources.pk3dir/gfx/icon16/pencil_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/pencil_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/pencil_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/phone.png create mode 100644 base/resources.pk3dir/gfx/icon16/phone_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/phone_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/phone_sound.png create mode 100644 base/resources.pk3dir/gfx/icon16/photo.png create mode 100644 base/resources.pk3dir/gfx/icon16/photo_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/photo_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/photo_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/photos.png create mode 100644 base/resources.pk3dir/gfx/icon16/picture.png create mode 100644 base/resources.pk3dir/gfx/icon16/picture_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/picture_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/picture_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/picture_empty.png create mode 100644 base/resources.pk3dir/gfx/icon16/picture_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/picture_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/picture_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/picture_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/picture_save.png create mode 100644 base/resources.pk3dir/gfx/icon16/pictures.png create mode 100644 base/resources.pk3dir/gfx/icon16/pilcrow.png create mode 100644 base/resources.pk3dir/gfx/icon16/pill.png create mode 100644 base/resources.pk3dir/gfx/icon16/pill_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/pill_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/pill_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/plugin.png create mode 100644 base/resources.pk3dir/gfx/icon16/plugin_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/plugin_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/plugin_disabled.png create mode 100644 base/resources.pk3dir/gfx/icon16/plugin_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/plugin_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/plugin_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/plugin_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/printer.png create mode 100644 base/resources.pk3dir/gfx/icon16/printer_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/printer_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/printer_empty.png create mode 100644 base/resources.pk3dir/gfx/icon16/printer_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/rainbow.png create mode 100644 base/resources.pk3dir/gfx/icon16/report.png create mode 100644 base/resources.pk3dir/gfx/icon16/report_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/report_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/report_disk.png create mode 100644 base/resources.pk3dir/gfx/icon16/report_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/report_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/report_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/report_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/report_magnify.png create mode 100644 base/resources.pk3dir/gfx/icon16/report_picture.png create mode 100644 base/resources.pk3dir/gfx/icon16/report_user.png create mode 100644 base/resources.pk3dir/gfx/icon16/report_word.png create mode 100644 base/resources.pk3dir/gfx/icon16/resultset_first.png create mode 100644 base/resources.pk3dir/gfx/icon16/resultset_last.png create mode 100644 base/resources.pk3dir/gfx/icon16/resultset_next.png create mode 100644 base/resources.pk3dir/gfx/icon16/resultset_previous.png create mode 100644 base/resources.pk3dir/gfx/icon16/rosette.png create mode 100644 base/resources.pk3dir/gfx/icon16/rss.png create mode 100644 base/resources.pk3dir/gfx/icon16/rss_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/rss_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/rss_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/rss_valid.png create mode 100644 base/resources.pk3dir/gfx/icon16/ruby.png create mode 100644 base/resources.pk3dir/gfx/icon16/ruby_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/ruby_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/ruby_gear.png create mode 100644 base/resources.pk3dir/gfx/icon16/ruby_get.png create mode 100644 base/resources.pk3dir/gfx/icon16/ruby_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/ruby_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/ruby_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/ruby_put.png create mode 100644 base/resources.pk3dir/gfx/icon16/script.png create mode 100644 base/resources.pk3dir/gfx/icon16/script_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/script_code.png create mode 100644 base/resources.pk3dir/gfx/icon16/script_code_red.png create mode 100644 base/resources.pk3dir/gfx/icon16/script_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/script_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/script_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/script_gear.png create mode 100644 base/resources.pk3dir/gfx/icon16/script_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/script_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/script_lightning.png create mode 100644 base/resources.pk3dir/gfx/icon16/script_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/script_palette.png create mode 100644 base/resources.pk3dir/gfx/icon16/script_save.png create mode 100644 base/resources.pk3dir/gfx/icon16/server.png create mode 100644 base/resources.pk3dir/gfx/icon16/server_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/server_chart.png create mode 100644 base/resources.pk3dir/gfx/icon16/server_compressed.png create mode 100644 base/resources.pk3dir/gfx/icon16/server_connect.png create mode 100644 base/resources.pk3dir/gfx/icon16/server_database.png create mode 100644 base/resources.pk3dir/gfx/icon16/server_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/server_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/server_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/server_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/server_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/server_lightning.png create mode 100644 base/resources.pk3dir/gfx/icon16/server_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/server_uncompressed.png create mode 100644 base/resources.pk3dir/gfx/icon16/shading.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_align_bottom.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_align_center.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_align_left.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_align_middle.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_align_right.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_align_top.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_flip_horizontal.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_flip_vertical.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_group.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_handles.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_move_back.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_move_backwards.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_move_forwards.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_move_front.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_rotate_anticlockwise.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_rotate_clockwise.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_square.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_square_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_square_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_square_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_square_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_square_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_square_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_square_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/shape_ungroup.png create mode 100644 base/resources.pk3dir/gfx/icon16/shield.png create mode 100644 base/resources.pk3dir/gfx/icon16/shield_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/shield_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/shield_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/sitemap.png create mode 100644 base/resources.pk3dir/gfx/icon16/sitemap_color.png create mode 100644 base/resources.pk3dir/gfx/icon16/sound.png create mode 100644 base/resources.pk3dir/gfx/icon16/sound_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/sound_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/sound_low.png create mode 100644 base/resources.pk3dir/gfx/icon16/sound_mute.png create mode 100644 base/resources.pk3dir/gfx/icon16/sound_none.png create mode 100644 base/resources.pk3dir/gfx/icon16/spellcheck.png create mode 100644 base/resources.pk3dir/gfx/icon16/sport_8ball.png create mode 100644 base/resources.pk3dir/gfx/icon16/sport_basketball.png create mode 100644 base/resources.pk3dir/gfx/icon16/sport_football.png create mode 100644 base/resources.pk3dir/gfx/icon16/sport_golf.png create mode 100644 base/resources.pk3dir/gfx/icon16/sport_raquet.png create mode 100644 base/resources.pk3dir/gfx/icon16/sport_shuttlecock.png create mode 100644 base/resources.pk3dir/gfx/icon16/sport_soccer.png create mode 100644 base/resources.pk3dir/gfx/icon16/sport_tennis.png create mode 100644 base/resources.pk3dir/gfx/icon16/star.png create mode 100644 base/resources.pk3dir/gfx/icon16/status_away.png create mode 100644 base/resources.pk3dir/gfx/icon16/status_busy.png create mode 100644 base/resources.pk3dir/gfx/icon16/status_offline.png create mode 100644 base/resources.pk3dir/gfx/icon16/status_online.png create mode 100644 base/resources.pk3dir/gfx/icon16/stop.png create mode 100644 base/resources.pk3dir/gfx/icon16/style.png create mode 100644 base/resources.pk3dir/gfx/icon16/style_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/style_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/style_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/style_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/sum.png create mode 100644 base/resources.pk3dir/gfx/icon16/tab.png create mode 100644 base/resources.pk3dir/gfx/icon16/tab_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/tab_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/tab_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/tab_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/table.png create mode 100644 base/resources.pk3dir/gfx/icon16/table_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/table_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/table_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/table_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/table_gear.png create mode 100644 base/resources.pk3dir/gfx/icon16/table_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/table_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/table_lightning.png create mode 100644 base/resources.pk3dir/gfx/icon16/table_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/table_multiple.png create mode 100644 base/resources.pk3dir/gfx/icon16/table_refresh.png create mode 100644 base/resources.pk3dir/gfx/icon16/table_relationship.png create mode 100644 base/resources.pk3dir/gfx/icon16/table_row_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/table_row_insert.png create mode 100644 base/resources.pk3dir/gfx/icon16/table_save.png create mode 100644 base/resources.pk3dir/gfx/icon16/table_sort.png create mode 100644 base/resources.pk3dir/gfx/icon16/tag.png create mode 100644 base/resources.pk3dir/gfx/icon16/tag_blue.png create mode 100644 base/resources.pk3dir/gfx/icon16/tag_blue_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/tag_blue_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/tag_blue_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/tag_green.png create mode 100644 base/resources.pk3dir/gfx/icon16/tag_orange.png create mode 100644 base/resources.pk3dir/gfx/icon16/tag_pink.png create mode 100644 base/resources.pk3dir/gfx/icon16/tag_purple.png create mode 100644 base/resources.pk3dir/gfx/icon16/tag_red.png create mode 100644 base/resources.pk3dir/gfx/icon16/tag_yellow.png create mode 100644 base/resources.pk3dir/gfx/icon16/telephone.png create mode 100644 base/resources.pk3dir/gfx/icon16/telephone_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/telephone_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/telephone_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/telephone_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/telephone_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/telephone_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/telephone_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/television.png create mode 100644 base/resources.pk3dir/gfx/icon16/television_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/television_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_align_center.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_align_justify.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_align_left.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_align_right.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_allcaps.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_bold.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_columns.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_dropcaps.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_heading_1.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_heading_2.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_heading_3.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_heading_4.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_heading_5.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_heading_6.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_horizontalrule.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_indent.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_indent_remove.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_italic.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_kerning.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_letter_omega.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_letterspacing.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_linespacing.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_list_bullets.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_list_numbers.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_lowercase.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_padding_bottom.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_padding_left.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_padding_right.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_padding_top.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_replace.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_signature.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_smallcaps.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_strikethrough.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_subscript.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_superscript.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_underline.png create mode 100644 base/resources.pk3dir/gfx/icon16/text_uppercase.png create mode 100644 base/resources.pk3dir/gfx/icon16/textfield.png create mode 100644 base/resources.pk3dir/gfx/icon16/textfield_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/textfield_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/textfield_key.png create mode 100644 base/resources.pk3dir/gfx/icon16/textfield_rename.png create mode 100644 base/resources.pk3dir/gfx/icon16/thumb_down.png create mode 100644 base/resources.pk3dir/gfx/icon16/thumb_up.png create mode 100644 base/resources.pk3dir/gfx/icon16/tick.png create mode 100644 base/resources.pk3dir/gfx/icon16/time.png create mode 100644 base/resources.pk3dir/gfx/icon16/time_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/time_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/time_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/timeline_marker.png create mode 100644 base/resources.pk3dir/gfx/icon16/transmit.png create mode 100644 base/resources.pk3dir/gfx/icon16/transmit_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/transmit_blue.png create mode 100644 base/resources.pk3dir/gfx/icon16/transmit_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/transmit_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/transmit_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/transmit_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/tux.png create mode 100644 base/resources.pk3dir/gfx/icon16/user.png create mode 100644 base/resources.pk3dir/gfx/icon16/user_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/user_comment.png create mode 100644 base/resources.pk3dir/gfx/icon16/user_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/user_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/user_female.png create mode 100644 base/resources.pk3dir/gfx/icon16/user_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/user_gray.png create mode 100644 base/resources.pk3dir/gfx/icon16/user_green.png create mode 100644 base/resources.pk3dir/gfx/icon16/user_orange.png create mode 100644 base/resources.pk3dir/gfx/icon16/user_red.png create mode 100644 base/resources.pk3dir/gfx/icon16/user_suit.png create mode 100644 base/resources.pk3dir/gfx/icon16/vcard.png create mode 100644 base/resources.pk3dir/gfx/icon16/vcard_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/vcard_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/vcard_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/vector.png create mode 100644 base/resources.pk3dir/gfx/icon16/vector_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/vector_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/wand.png create mode 100644 base/resources.pk3dir/gfx/icon16/weather_clouds.png create mode 100644 base/resources.pk3dir/gfx/icon16/weather_cloudy.png create mode 100644 base/resources.pk3dir/gfx/icon16/weather_lightning.png create mode 100644 base/resources.pk3dir/gfx/icon16/weather_rain.png create mode 100644 base/resources.pk3dir/gfx/icon16/weather_snow.png create mode 100644 base/resources.pk3dir/gfx/icon16/weather_sun.png create mode 100644 base/resources.pk3dir/gfx/icon16/webcam.png create mode 100644 base/resources.pk3dir/gfx/icon16/webcam_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/webcam_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/webcam_error.png create mode 100644 base/resources.pk3dir/gfx/icon16/world.png create mode 100644 base/resources.pk3dir/gfx/icon16/world_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/world_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/world_edit.png create mode 100644 base/resources.pk3dir/gfx/icon16/world_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/world_link.png create mode 100644 base/resources.pk3dir/gfx/icon16/wrench.png create mode 100644 base/resources.pk3dir/gfx/icon16/wrench_orange.png create mode 100644 base/resources.pk3dir/gfx/icon16/xhtml.png create mode 100644 base/resources.pk3dir/gfx/icon16/xhtml_add.png create mode 100644 base/resources.pk3dir/gfx/icon16/xhtml_delete.png create mode 100644 base/resources.pk3dir/gfx/icon16/xhtml_go.png create mode 100644 base/resources.pk3dir/gfx/icon16/xhtml_valid.png create mode 100644 base/resources.pk3dir/gfx/icon16/zoom.png create mode 100644 base/resources.pk3dir/gfx/icon16/zoom_in.png create mode 100644 base/resources.pk3dir/gfx/icon16/zoom_out.png create mode 100644 base/resources.pk3dir/scripts/bots.txt delete mode 100644 base/resources.pk3dir/textures/ui/avatar_missing.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/cancel.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/cancel.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/cd.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/cd.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/console.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/console.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/desktop.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/desktop.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/disconnect.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/disconnect.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/encrypted.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/encrypted.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/exec.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/exec.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/exit.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/exit.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/folder.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/folder.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/gear.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/gear.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/hdd.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/hdd.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/help-open.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/help-open.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/help.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/help.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/important.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/important.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/music.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/music.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/refresh.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/refresh.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/save.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/save.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/server-new.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/server-new.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/servers.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/servers.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/shred.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/shred.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/socket.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/socket.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/track-full.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/track-full.tga delete mode 100644 base/resources.pk3dir/textures/ui/icons/trash.mat delete mode 100644 base/resources.pk3dir/textures/ui/icons/trash.tga delete mode 100644 base/resources.pk3dir/textures/ui/m_bottom.mat delete mode 100644 base/resources.pk3dir/textures/ui/m_bottomleft.mat delete mode 100644 base/resources.pk3dir/textures/ui/m_bottomright.mat delete mode 100644 base/resources.pk3dir/textures/ui/m_left.mat delete mode 100644 base/resources.pk3dir/textures/ui/m_linebottom.mat delete mode 100644 base/resources.pk3dir/textures/ui/m_linebottomleft.mat delete mode 100644 base/resources.pk3dir/textures/ui/m_linebottomright.mat delete mode 100644 base/resources.pk3dir/textures/ui/m_lineleft.mat delete mode 100644 base/resources.pk3dir/textures/ui/m_linemid.mat delete mode 100644 base/resources.pk3dir/textures/ui/m_lineright.mat delete mode 100644 base/resources.pk3dir/textures/ui/m_linetop.mat delete mode 100644 base/resources.pk3dir/textures/ui/m_linetopleft.mat delete mode 100644 base/resources.pk3dir/textures/ui/m_linetopright.mat delete mode 100644 base/resources.pk3dir/textures/ui/m_mid.mat delete mode 100644 base/resources.pk3dir/textures/ui/m_right.mat delete mode 100644 base/resources.pk3dir/textures/ui/m_top.mat delete mode 100644 base/resources.pk3dir/textures/ui/m_topleft.mat delete mode 100644 base/resources.pk3dir/textures/ui/m_topright.mat delete mode 100644 base/resources.pk3dir/textures/ui/steam/icon_checked.mat delete mode 100644 base/resources.pk3dir/textures/ui/steam/icon_close.mat delete mode 100644 base/resources.pk3dir/textures/ui/steam/icon_down.mat delete mode 100644 base/resources.pk3dir/textures/ui/steam/icon_emptybox.mat delete mode 100644 base/resources.pk3dir/textures/ui/steam/icon_radiosel.mat delete mode 100644 base/resources.pk3dir/textures/ui/steam/icon_radiounsel.mat delete mode 100644 base/resources.pk3dir/textures/ui/steam/icon_resizer.mat delete mode 100644 base/resources.pk3dir/textures/ui/steam/icon_up.mat delete mode 100644 base/resources.pk3dir/textures/ui/voice_off.mat delete mode 100644 base/resources.pk3dir/textures/ui/voice_on.mat create mode 100644 base/src/client/hud.qc create mode 100644 base/src/rules/Makefile create mode 100644 base/src/rules/deathmatch.qc create mode 100644 base/src/rules/singleplayer.qc delete mode 100644 base/test_maps.pk3dir/maps/test/func_chargers.bak delete mode 100644 base/test_maps.pk3dir/maps/test/func_chargers.prt delete mode 100644 base/test_maps.pk3dir/maps/test/func_chargers.srf delete mode 100644 base/test_maps.pk3dir/maps/test/mapscript.bak delete mode 100644 base/test_maps.pk3dir/maps/test/mapscript.prt rename base/test_maps.pk3dir/maps/test/{mapscript.mapC => mapscript.qc} (78%) delete mode 100644 base/test_maps.pk3dir/maps/test/mapscript.srf create mode 100644 base/test_maps.pk3dir/maps/test/ui.qc delete mode 100644 base/test_maps.pk3dir/maps/test/weapons.bak delete mode 100644 base/test_maps.pk3dir/maps/test/weapons.srf create mode 100644 base/test_maps.pk3dir/models/logo.iqm rename src/{menu-vgui/background.qc => client/api.h} (68%) mode change 100755 => 100644 create mode 100644 src/client/api.qc create mode 100644 src/client/api_func.h create mode 100644 src/client/commandmenu.qc create mode 100644 src/client/hud.h create mode 100644 src/client/hud.qc create mode 100644 src/client/spawnmenu.qc create mode 100644 src/cvar_defaults.cfg create mode 100644 src/gs-entbase/server/target_speaker.qc create mode 100644 src/gs-entbase/shared/func_useableladder.qc delete mode 100644 src/menu-fn/background.qc mode change 100755 => 100644 src/menu-vgui/desktop.qc mode change 100755 => 100644 src/menu-vgui/loading.qc mode change 100755 => 100644 src/menu-vgui/ui_createserver.qc create mode 100644 src/menu-vgui/ui_customgame.qc mode change 100755 => 100644 src/menu-vgui/ui_findservers.qc create mode 100644 src/menu-vgui/ui_loadgame.qc mode change 100755 => 100644 src/menu-vgui/ui_musicplayer.qc mode change 100755 => 100644 src/menu-vgui/ui_newgame.qc mode change 100755 => 100644 src/menu-vgui/ui_quitgame.qc create mode 100644 src/platform/background.h create mode 100755 src/platform/background.qc rename src/{server/mapC_math.h => platform/init.h} (86%) create mode 100644 src/platform/init.qc create mode 100644 src/platform/saves.h create mode 100644 src/platform/saves.qc create mode 100644 src/platform/servers.h create mode 100644 src/platform/servers.qc create mode 100644 src/server/api.h create mode 100644 src/server/api.qc create mode 100644 src/server/api_func.h delete mode 100644 src/server/mapC.h delete mode 100644 src/server/mapC_weapons.h create mode 100644 src/shared/NSRagdoll.h create mode 100644 src/shared/NSRagdoll.qc create mode 100644 src/shared/api.h create mode 100644 src/shared/api.qc create mode 100644 src/shared/input.h create mode 100644 src/shared/teams.h create mode 100644 src/vgui/ui_commandbutton.qc create mode 100644 src/vgui/ui_console.qc create mode 100644 src/vgui/ui_loadingpanel.qc create mode 100644 src/vgui/ui_progressbar.qc diff --git a/.gitignore b/.gitignore index 00ad69ef..34512f4a 100644 --- a/.gitignore +++ b/.gitignore @@ -56,6 +56,7 @@ ssqccore.txt # Ideally you would add # your project here as well +action/ AbsoluteZero/ base_pbr/ baseq2/ @@ -93,6 +94,9 @@ ship/ tf/ tf2/ tfc/ +dk/ +basedk/ +mainkp/ ts/ valve/ wastes/ diff --git a/Documentation/About.md b/Documentation/About.md new file mode 100644 index 00000000..7da77973 --- /dev/null +++ b/Documentation/About.md @@ -0,0 +1,57 @@ + +# About The Project {#about} + +The Nuclide project produces a freely available game-logic component and +development platform on top of [FTEQW](https://www.fteqw.org); which is a featureful QuakeWorld-based engine. + +**The general idea is that Nuclide takes care of ~90% of the code you shouldn't have to worry about.** + +It is targetted towards developers with a background/interest in id Technology. + +It comes with a simple example game (simply referred to as 'Base') and some test maps. There's also some other, third-party example projects. + +General feature overview: + +- The 'missing' SDK for engines like FTEQW +- Support for client-side predicted movement, weaponry and vehicles +- Documented APIs for everything you need to interface with the engine +- APIs and Frameworks for managing updates, mods, servers, and platform specific features +- Complete re-implementations of hundreds of entities, from GoldSrc/Source engine games +- Entity communication via traditional one-way triggers, or our Source Engine I/O compatible system +- Includes BotLib, a framework for multiplayer-AI that can receive game-specific overrides +- Includes VGUILib, a re-imagining of Valve's GUI library, which can also be used for in-game surface based interfaces +- Designed to be familar to developers coming from GoldSrc/Source +- VR/XR aware codebase +- All permissively licensed + + +# Frequently Asked Questions + +## 1. Why might I want to use it? {#why} + +You might be migrating from an engine that is no longer being licensed and don't want to learn a new engine and toolchain. + +You might want to develop a game using a lot of complex and well-tested objects +which might be tedious to implement on your own. + +You might want to run or make modifications for a game using Nuclide and need full +control over what you can do. + +## 2. How free is Nuclide? {#license} + +Everything in Nuclide is **free software**. The copyright terms for the game-logic are +very permitting. Nuclide *does not use the GPL* as a point of reference in terms of license, it instead uses a **ISC-like license**. This means you can use, copy, modify and +distribute the code and work resulting from it for any purpose. + +**Please read the very short 'LICENSE' document for details.** + +## 3. What are the alternatives? {#alternatives} + +Implementing systems such as prediction, complex map objects and entities on +your own, from scratch - or licensing another engine such as [Source](https://partner.steamgames.com/doc/sdk/uploading/distributing_source_engine) that ships with its own **Source SDK Base**. + +## 4. Any example projects? {#examples} + +- [The Wastes](https://store.steampowered.com/app/793670) is a commerical game built using Nuclide. +- [Rad-Therapy](https://www.github.com/eukara/freehl) is a clone of 'Half-Life: Deathmatch' on Nuclide. +- [Tactical Retreat](https://www.github.com/eukara/freecs) is a clone of 'Counter-Strike', for Rad-Therapy. diff --git a/Documentation/Decl.md b/Documentation/Decl.md deleted file mode 100644 index ee64654b..00000000 --- a/Documentation/Decl.md +++ /dev/null @@ -1,6 +0,0 @@ -# Defs/Declarations {#scripting} - -Explanation of declaration-based subsystems within Nuclide. - -These usually contain key/value pair type parameters (and more, depending on the type) -within the game. They help a great deal in managing complexity between reusable components. That way the game code can focus on everything that's not unique. diff --git a/Documentation/DoxygenLayout.xml b/Documentation/DoxygenLayout.xml new file mode 100644 index 00000000..268a5992 --- /dev/null +++ b/Documentation/DoxygenLayout.xml @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Documentation/Footer.html b/Documentation/Footer.html new file mode 100644 index 00000000..dd08fe30 --- /dev/null +++ b/Documentation/Footer.html @@ -0,0 +1 @@ +Nuclide is a project by [Vera Visions, L.L.C.](https://www.vera-visions.com/) diff --git a/Documentation/GettingStarted.md b/Documentation/GettingStarted.md new file mode 100644 index 00000000..9b69a818 --- /dev/null +++ b/Documentation/GettingStarted.md @@ -0,0 +1,12 @@ +# Getting started + +## How to get the latest version {#how} + +You clone the Nuclide git repository first. There's multiple places to get it, one such place may be GitHub: + +`git clone https://github.com/veravisions/nuclide` + +You can then update the git repository as you normally would. Using `git pull` for example. + +And then you can [get started on building the engine and the rest of the toolchain](Building.md). Alternatively, you can also move in the official FTEQW binaries into the Nuclide directory to get started without bootstrapping your own engine + QuakeC compiler. +C programming knowledge is not required to use Nuclide itself. diff --git a/Documentation/History.md b/Documentation/History.md index 7380234c..a547949b 100644 --- a/Documentation/History.md +++ b/Documentation/History.md @@ -29,7 +29,7 @@ A lot had been learned about prediction and taking full advantage of the custom networking available in **FTEQW**, but new features have also been added to the engine to take full advantage of what the content had to offer: -Features like interacting with [OpenAL's EAX extension](EFX.md), [model-events](VVM.md), support +Features like interacting with [OpenAL's EAX extension](@ref efx), [model-events](VVM.md), support for WAD3 decal parsing and countless QuakeC extensions were all added by either Spike (FTEQW Author) or eukara himself to make everything possible. diff --git a/Documentation/ReadMe.md b/Documentation/ReadMe.md index 45ed366f..4cd181c6 100644 --- a/Documentation/ReadMe.md +++ b/Documentation/ReadMe.md @@ -4,89 +4,23 @@ Welcome to the manual for **Nuclide**! -This is a game development kit (GDK) and development environment created by [Vera Visions, L.L.C.](https://www.vera-visions.com/). We want to share it with everyone to avoid duplicate effort and in the hopes that it is useful to someone else. +![](brick.png) This is a game development kit (GDK) and development environment for id Tech, using GPL QuakeWorld technology. We are sharing it in the hopes that it is useful! -### What this project is {#what} +[You can read more in-depth information, such as features here](About.md). -The Nuclide project produces a freely available game-logic component and -development platform on top of [FTEQW](https://www.fteqw.org); which is the engine we happen to use. +## Learning Resources -**The general idea is that Nuclide takes care of ~90% of the code you shouldn't have to worry about.** +![](hourglass.png) [Getting Started](GettingStarted.md) -The goal is to create a modern research base for new advancements, as well -as to have a stable base with a decent API for making games. +![](table.png) [Guide To Decl Files](@ref decl) -It is targetted towards developers with a background/interest in id Technology. +![](table_edit.png) [Creating Weapons](@ref NSWeapon) -It comes with a simple example game (simply referred to as 'Base') and some test maps. There's also some other, third-party example projects. +![](table_edit.png) [Creating Items](@ref NSItem) -General feature overview: +![](page_code.png) [Writing Game Rules](@ref NSGameRules) -- The 'missing' SDK for engines like FTEQW -- Support for client-side predicted movement, weaponry and vehicles -- Documented APIs for everything you need to interface with the engine -- APIs and Frameworks for managing updates, mods, servers, and platform specific features -- Complete re-implementations of hundreds of entities, from GoldSrc/Source engine games -- Entity communication via traditional one-way triggers, or our Source Engine I/O compatible system -- Includes BotLib, a framework for multiplayer-AI that can receive game-specific overrides -- Includes VGUILib, a re-imagining of Valve's GUI library, which can also be used for in-game surface based interfaces -- Designed to be familar to developers coming from GoldSrc/Source -- VR/XR aware codebase -- All permissively licensed -### 1. Why might I want to use it? {#why} +## Contributing -You might be migrating from an engine that is no longer being licensed and don't want to learn a new engine and toolchain. - -You might want to develop a game using a lot of complex and well-tested objects -which might be tedious to implement on your own. - -You might want to run or make modifications for a game using Nuclide and need full -control over what you can do. - -### 2. How free is Nuclide? {#license} - -Everything in Nuclide is **free software**. The copyright terms for the game-logic are -very permitting. Nuclide *does not use the GPL* as a point of reference in terms of license, it instead uses a **ISC-like license**. This means you can use, copy, modify and -distribute the code and work resulting from it for any purpose. - -**Please read the very short 'LICENSE' document for details.** - -### 3. What are the alternatives? {#alternatives} - -Implementing systems such as prediction, complex map objects and entities on -your own, from scratch - or licensing another engine such as [Source](https://partner.steamgames.com/doc/sdk/uploading/distributing_source_engine) that ships with its own **Source SDK Base**. - -### 4. Any example projects? {#examples} - -- [The Wastes](https://store.steampowered.com/app/793670) is a commerical game built using Nuclide. -- [FreeHL](https://www.github.com/eukara/freehl) is a free-software, clean-room clone of Half-Life: Deathmatch also built using Nuclide. -- [FreeCS](https://www.github.com/eukara/freecs) exists in the same vein as FreeHL, but targetting a recreation of Counter-Strike v1.5 (mod version) specifically. - -## Getting started {#prerequisites} - -First of all, you want to be sure this is what you want to get into. -If you do posess a basic knowledge of the following: - -- The C programming language -- Debugging a native application -- Makefiles -- Compiling your own binaries -- Concept of public and private APIs -- QuakeC - -Then you will have a good time. -We strive to keep the codebase portable and conform to open standards wherever possible. -This means that if you develop on Windows, you probably want to install something like WSL or even [Cygwin](https://www.cygwin.com/) to make this bearable. - -Please don't ask us how to use WSL or Cygwin. We do not provide support for either. We do not develop on Windows! Sorry. - -**This is a development kit and a development environment. This is not a game.** - -## Actually getting started {#how} - -You clone the Nuclide git repository first. There's multiple places to get it, one such place may be GitHub: - -`git clone https://github.com/veravisions/nuclide` - -And then you can [get started on building the engine and the rest of the toolchain](Building.md). Alternatively, you can also move in the official FTEQW binaries into the Nuclide directory to get started without bootstrapping your own engine + QuakeC compiler. \ No newline at end of file +![](bug.png) You can contribute by filing bugs [here](https://www.github.com/veravisions/nuclide). diff --git a/Documentation/footer.html b/Documentation/footer.html new file mode 100644 index 00000000..5880adbf --- /dev/null +++ b/Documentation/footer.html @@ -0,0 +1,17 @@ + + + + + + + + + + diff --git a/Doxyfile b/Doxyfile index 49bb763f..dbfe97b0 100644 --- a/Doxyfile +++ b/Doxyfile @@ -244,7 +244,7 @@ SEPARATE_MEMBER_PAGES = NO # uses this value to replace tabs by spaces in code fragments. # Minimum value: 1, maximum value: 16, default value: 4. -TAB_SIZE = 8 +TAB_SIZE = 4 # This tag can be used to specify a number of aliases that act as commands in # the documentation. An alias has the form: @@ -741,7 +741,7 @@ SHOW_USED_FILES = YES # (if specified). # The default value is: YES. -SHOW_FILES = YES +SHOW_FILES = NO # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces # page. This will remove the Namespaces entry from the Quick Index and from the @@ -772,7 +772,7 @@ FILE_VERSION_FILTER = # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. -LAYOUT_FILE = +LAYOUT_FILE = Documentation/DoxygenLayout.xml # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib @@ -876,6 +876,8 @@ WARN_LOGFILE = INPUT = src/ \ Documentation/ReadMe.md \ + Documentation/About.md \ + Documentation/GettingStarted.md \ Documentation/Building.md \ Documentation/Dependencies.md \ Documentation/Launching.md \ @@ -1016,6 +1018,7 @@ EXAMPLE_RECURSIVE = NO IMAGE_PATH = Documentation/Materials/ \ Documentation/Images/ \ + base/resources.pk3dir/gfx/icon16/ # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program @@ -1230,7 +1233,7 @@ HTML_HEADER = # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_FOOTER = +HTML_FOOTER = Documentation/footer.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of diff --git a/Makefile b/Makefile index 0a600451..78ba94c0 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,7 @@ # Nuclide Makefile # # Apr 2024 by Marco Cawthorne +# Last updated: 2024/10/12 # # set `GAME` when issuing make. E.g. `make GAME=wastes` @@ -14,6 +15,8 @@ GAME_EXT= GAME_BINARY=$(NAME)_$(GAME_ARCH)$(GAME_EXT) GAMEDS_BINARY=$(NAME)DS_$(GAME_ARCH)$(GAME_EXT) +ENGINE_URL=https://www.github.com/fte-team/fteqw + # FTE specific builds ENGINE_ARCH=amd64 ENGINE_CLBUILD=m-dbg @@ -56,6 +59,7 @@ help: all: game engine dedicated plugins game: fteqcc + -cp src/cvar_defaults.cfg "$(GAME)/zpak001.pk3dir/default_cvar.cfg" cd "$(GAME)/src/" && $(MAKE) QCC=$(QCC_DIR)/../../fteqcc client: fteqcc @@ -148,6 +152,10 @@ clean-engine: cd ThirdParty/fteqw/engine && $(MAKE) clean -rm $(NAME)_x64$(GAME_EXT) $(NAME)_x86$(GAME_EXT) $(NAME)DS_x64$(GAME_EXT) $(NAME)DS_x86$(GAME_EXT) fteqw fteqw-sv +clean-fteqw: + cd ThirdParty/fteqw/engine && $(MAKE) clean + -rm fteqw fteqw-sv + clean-tools: cd Tools/vmap && $(MAKE) clean cd Tools/vvmtool && $(MAKE) clean @@ -157,7 +165,7 @@ clean-tools: update: if [ -f ./.git/config ];then git pull;fi if [ -f $(GAME)/.git/config ];then cd $(GAME) && git pull;fi - if [ ! -d ThirdParty/fteqw ];then git clone https://www.github.com/fte-team/fteqw ThirdParty/fteqw;else cd ./ThirdParty/fteqw && git pull;fi + if [ ! -d ThirdParty/fteqw ];then git clone $(ENGINE_URL) ThirdParty/fteqw;else cd ./ThirdParty/fteqw && git pull;fi if [ ! -d Tools/vvmtool ];then git clone https://github.com/VeraVisions/vvmtool Tools/vvmtool;else cd ./Tools/vvmtool && git pull;fi if [ ! -d Tools/vmap ];then git clone https://github.com/VeraVisions/vmap Tools/vmap;else cd ./Tools/vmap && git pull;fi if [ ! -d Tools/worldspawn ];then git clone https://github.com/VeraVisions/worldspawn Tools/worldspawn;else cd ./Tools/worldspawn && git pull;fi diff --git a/README.md b/README.md index d71beae4..5ce05d51 100644 --- a/README.md +++ b/README.md @@ -16,3 +16,8 @@ Run the engine in the root of this repository, after having issued `make progs G You can build your own offline version of the online manual by running `doxygen` in the root of this repository. The output will be under **Documentation/html/index.html**. +# Credits + +Silk Icons: https://github.com/markjames/famfamfam-silk-icons +Flag Icons: https://github.com/markjames/famfamfam-flag-icons +https://heyter.github.io/js-famfamfam-search/ \ No newline at end of file diff --git a/base/engine.h b/base/engine.h index 9bf4c5f7..d4b2745b 100644 --- a/base/engine.h +++ b/base/engine.h @@ -43,7 +43,7 @@ #define USEAREAGRID /* leave it on, improves performance */ #define AVAIL_DINPUT /* input for Windows */ #define AVAIL_FREETYPE /* for truetype font rendering */ -#define AVAIL_STBI /* avoid libpng/libjpeg dependancies */ +#undef AVAIL_STBI /* avoid libpng/libjpeg dependancies */ #define ENGINE_ROUTING /* engine-side, fast routing */ #ifndef LEGACY_GPU @@ -140,8 +140,8 @@ #undef HAVE_SPEEX /* .xz decompression */ #undef AVAIL_GZDEC /* .gz decompression */ #undef PACKAGE_DZIP /* .dzip special-case archive support */ -#undef AVAIL_PNGLIB /* .png image format support (read+screenshots) */ -#undef AVAIL_JPEGLIB /* .jpeg image format support (read+screenshots) */ +#define AVAIL_PNGLIB /* .png image format support (read+screenshots) */ +#define AVAIL_JPEGLIB /* .jpeg image format support (read+screenshots) */ #undef AVAIL_MP3_ACM /* .mp3 support (in windows). */ #undef IMAGEFMT_DDS #undef IMAGEFMT_PKM @@ -192,8 +192,8 @@ #undef IMAGEFMT_PSD #undef IMAGEFMT_XCF #undef IMAGEFMT_LMP -#undef IMAGEFMT_PNG -#undef IMAGEFMT_JPG +#define IMAGEFMT_PNG +#define IMAGEFMT_JPG #undef IMAGEFMT_GIF #undef IMAGEFMT_EXR #undef IPLOG diff --git a/base/resources.pk3dir/decls/def/player.def b/base/resources.pk3dir/decls/def/player.def index 90aa44a5..3c666d54 100644 --- a/base/resources.pk3dir/decls/def/player.def +++ b/base/resources.pk3dir/decls/def/player.def @@ -1,6 +1,7 @@ entityDef player { - "spawnclass" "NSClientPlayer" + "spawnclass" "NSClientPlayer" + "model" "models/player.vvm" } entityDef player_mp diff --git a/base/resources.pk3dir/default.cfg b/base/resources.pk3dir/default.cfg index e9557811..3553b1b1 100644 --- a/base/resources.pk3dir/default.cfg +++ b/base/resources.pk3dir/default.cfg @@ -1,5 +1,4 @@ -// Standard Game Bindings -// Feel free to modify them however you like +exec default_cvar.cfg // Clear all bindings... unbindall @@ -17,10 +16,16 @@ bind MWHEELUP "weapprev" bind MWHEELDOWN "weapnext" // Interact button -bind e "+use" +bind q "+leanleft" +bind e "+leanright" +bind f "+use" -// Flashlight button -bind f "impulse 100" +bind shift "+sprint" + +set pm_walkspeed "190" +set pm_runspeed "320" +set pm_stepheight "18" +set pm_airstepheight "18" // Misc interface buttons bind t "messagemode" diff --git a/base/resources.pk3dir/fonts/centerprint.font b/base/resources.pk3dir/fonts/centerprint.font new file mode 100644 index 00000000..34f2c508 --- /dev/null +++ b/base/resources.pk3dir/fonts/centerprint.font @@ -0,0 +1,2 @@ +path fonts/IBMPlexMono-Text.otf +size 16 \ No newline at end of file diff --git a/base/resources.pk3dir/gfx/flags16/CREDITS b/base/resources.pk3dir/gfx/flags16/CREDITS new file mode 100644 index 00000000..9bebbb70 --- /dev/null +++ b/base/resources.pk3dir/gfx/flags16/CREDITS @@ -0,0 +1,3 @@ +Flag Icons by Mark James +https://github.com/markjames/famfamfam-flag-icons +http://www.famfamfam.com/lab/icons/flags/ diff --git a/base/resources.pk3dir/gfx/flags16/ad.png b/base/resources.pk3dir/gfx/flags16/ad.png new file mode 100755 index 0000000000000000000000000000000000000000..625ca84f9ec596848d4b967b5556fda897ca7183 GIT binary patch literal 643 zcmV-}0(||6P)S}{rU-#^xW|9%5S{`_G8k=zVG=|5luWB>#JF#yj01oZa& zTu&JQ008~}|NQ&{0055x0sR95`v3p?1_t~7{`v!N`v3d-{`&g=`T6amqXIBA$0h)T zKokWRkpoMx|Go@O4FvhR>O1p+i7`B6t^3)y2dJ<#?4I?d4x-E}Az98Z`2`TmzkmP! z{`(J9{pauh-+zJD{JOYLhW+QSzkh#x`Y&wke*WLjpZ~u9`2XuCr@{^OJ|MkZb_UGR@Z=V>fB*iaq<8P{*B}2u-uMnu#J~U$KrBDL0bT$1_irEqiZcM6WEF7g<|*+% zzkjHi-TwRc=f7_t9|K*?`1?07lmG&V<)V$@{}>pUYZ(~+fDw@M3(WY1!T<=sp}f-o0K!lJ3<>Jc!&VtMslE3ph2^H3FGe(F z4|^}slF1@l1Nxc}^5hjjU=0la|37)k@b@neJ^1|l@87?_{{z(l6@kcKe}Db@_Y267 z<&g#201!YdV6*>2R0EZ*bYA%%2Vi7me5m>mAb?naPGtnD20MY__n-f`0mzg8{s9CK z*hzmtW)s%H$oS{aAAkS?JLxaT`2W9u;n%DD1Q-B%#%TuGpFSS|0000&5HW|5#c7{r(N){s9YCi84$~U|{$Glm>AD0*K|^yLU}ZO+eP) ze;~;4`#0mCzs$dX{r~-&?f370zkUTM{{OB1_1E8DKmYz*JbN)f0I>i8Q1#1Kum1f0 z{pZggpt}FRe*ORX>;JEx|9}4c_w(m__W!pfKK=atLxM{ZXbC_7vHbh@@9*EgK-ECy zzkh)Y{?EYhFEQc&-#`EN9{7Lq7*OE*@9)2U|NQmmC(vO40VtezBLF}U2%?OI(TG)& zJC>!~;SYmN-)zb6gc(7A-^Q(#z0vHb9!CJ#T#ii{@&pjek8j`pfX)5|H00+GpnLvt za{MtfWBC4qk%R63j~{=2{QLgr`wyTb*amx2hce{;{QL3a|BhWh#6A5bKmf5of*%NgdVm^$Zuo!gI_LQd|G=96g51yWl0Agf71rLE? q3XWqq@&Lw?Iyk0*94-cc00RK~MQKxxUU$F%0000= z`}|7!`YQYT5C8xIh~*yx1DgQ1_jkSr_QgN{Gn)!7=zkRT=l(yS{y%^Jd$>%yrP!)vVq~xpZ~xA{{HjZ>hB|)Z~OQoBLBm{yCqA0{k;C`&+mV~|1$jj15^wU zKukakbkF}kzkmk({q_6zmUTZaUWBOraqa5!?(V-pgMR}R{04?0&`AIR#PSE^hrdi> z;*7t4gLVFSJ$J5DTibsorq@%ai5h7B2l^1G@*gM=fUW@uAjYc<48V{DX@ijvE(11_ dg@FMezyQzuBHsGv+i3s*002ovPDHLkV1jTADB=JB literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/ai.png b/base/resources.pk3dir/gfx/flags16/ai.png new file mode 100755 index 0000000000000000000000000000000000000000..74ed29d92616c86757d3c0ec04378301c8f591b4 GIT binary patch literal 643 zcmV-}0(||6P)ocPy#thD++(+#W%SS0Qvp^`1%0+_yGC)0QUL-|M&m^ z`T_tk0M7pe&iDc7fh@K74M*k&0{8f*88BG;;GY6ve?;&4{{Q>_{{8&^`u+g@|Ns5} z|C?Nv0*Gb#mu+n4z6ZW~#qjy_|6ji&ZeIEMk16oyzH)i@Pk$MNxLARR?a#kwpMS72 zF)}cG2M8dRUN*~81wCz%$A2$f`_IL|A|w6j^RHtc7{2`lYG-KkQ{(*knSqh%3kzr7 zs%s1kKL7#%F#yj00-^B^D;pD^^AqC)4C(?1m>@q26ceiU4*2{4`u_d~@vQ*ykp&A1 z3h$o${r~^~`vQo?Pm-bY@cm79zVQG5%l!B6)Riap%L`bGemnT<@2|iAfl64!%YWS~ z`p0YY_dig_cYpw5WYAmG*lPLk!;jy8|NZ#~MF0Q%{rCG1ko^Di`(Fhkd3F{?py0c9Vg{{gA~^#>F<|Nj5KapBR^@Bf~CXSi|t;lF=C z8-4)<5DUX^V9+rDCI3RuUy#}V{s46X!}R~}@4ug&fA|+@;n!b(1zCZ900KKMX({{sIILBZE*UQbc|SngJt$+`m9Kz!<;5 dBm+Qz0RWL%NC2%sdjkLf002ovPDHLkV1lARHI@JX literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/al.png b/base/resources.pk3dir/gfx/flags16/al.png new file mode 100755 index 0000000000000000000000000000000000000000..92354cb6e257be2cade71cb825027ce8d9efc06d GIT binary patch literal 600 zcmV-e0;m0nP)PbXFRCwBA zyv)hK@{fUmi2(>${xJOc&A`II@PmN?BKC`c;SU)710$d~Kmf4-r6niy16BY3`}g0! ze=L9h&Uybegp-Ns@87v^zGQMU|NZla@z1Y+zkdVKmFbHB0*HkH4F0@)&iwE1;&GRLuzkX(OGXMMa``@o$|Ni_2x(y(Jn3#TnHT?el|IhC;U%pHK`}6Df z@2@|9J^lXU=Z~KvfBzi*^!4A*U;lv`e*Fge3Lt=(82$q_`~m9z|ND;$!(WEqze~6o ze}X|JFO$H(U+VvX#{c{avi3L7@c;n?3L&6l7=Hix`}emN<6i~#|7+iUWBL8-&##}m zKKx5zXJr5LA80nvkwCM6egFs{po9Y?& zL6B;olm7ns#=rm&Kp-3b{RIXY(1{??Ha=$NKfkS+|9@us$Mfg+93j@fzkY#y2y!;i z&kO(o1PWH5>zPHwn7|>;0Mz;WPl13iP!Y(WKYy4&4hBXMSPugOKmaiw2gk!dq!|4J mj$lZE0R~eis zC&uN{cDQ8`!@ZNLOqwtoG6nhzPx}SV-d6yzFfcIz75{(rngJyDkKrFw8iaoThHCr$ zo8k9wMhS^O3=9AP!~%5B|9}4(ASQtkLN$m1CV&5705X362095KfLKJhW;OjWdGY7l zzrX*$DuLu*pcFC#NdEr)SL!$SY=)lz0mSm_*B_u)|AM4JP)(}33zy1Lc&_o7? zKL7y)bkd){fBym<_v`mxpbeRs`+WRVot-5A{r$IX$CJFg13u{3eX_{0R++j zR}GCkSy{&4zk!krKoTg(2n-k?g31B}5JW!NMq0d0000q< zM7LZb@rX?|r)2RP-+aO3(7q?c3+$-Vv0E)PxM3SDV%@s`#GkZvw_x^WBa~uq3^l}t zWdf(j(=(>^SgETc#5#EZT(4ObRkfxbzP9G;yza0;Ygc8-_*?EP(ca#`l6-Z6D0{tL zQ4|~MCSi!9Q9YkW=V$ix#EqZ!rc?eWA0TwdVID+3aqrYUXUhCI)Ad5!(cP!BhhW$Ayb2&r8kK!bz*2`~UE W(Ndrek0Jg50000NL7TW{{R0! zJP>i}(MpzaSkj z=eqvqa`^|6{{QbQRQ11q3~Vg_kG}Z}5I`(hw}ncX8D4$|h64jUK>or*=^r$dfI%n0 z$3MKz;!F0w91GjkkV%_X`@4 wKR^hm`X5LwD9*v?4;TUC6Bz$&3;+QJ0QLcJ=WT{TU;qFB07*qoM6N<$f>3bX%K!iX literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/as.png b/base/resources.pk3dir/gfx/flags16/as.png new file mode 100755 index 0000000000000000000000000000000000000000..32f30e4ce4eedd22d4f09c4f3a46c52dd064f113 GIT binary patch literal 647 zcmV;20(kw2P);Rmc0RI30 z|Nj5|{Q>>`0R8>{{QLs@`vM01^D6+%Ap+Y10Qw3Sr3ED)s=c}b05Jg0{{#dC0RR60 z)z$y}`~dv>0Q&p?0Q>ne0Khr|#}EMN1`-ttJvaFq6VTDg`OMJS*4F}vg#m0fQ1$QM z42u6QTCg3Kt8+Li1J#Y_zUd>4Lw{URe1tEjLbKmY(S0M7pd(g2qsJ0|z;{R`~d z`n<6E*3bb41p*Zr{{R344LkeqyaMyV01O!W0PZ0+TjlEQ0st`p&i?@b0Q{Gi0m{n% z`T6-B``1JQx+4kM0{rp_FfRy7P6Qq%_1|&<`|JPx`Uew8u)+%h2+ zdiAI7xt}_}e|$CmbI9$2>u h*D)|iF)#oG7yty8`q2#I8zBGy002ovPDHLkV1j5VEF}N{ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/at.png b/base/resources.pk3dir/gfx/flags16/at.png new file mode 100755 index 0000000000000000000000000000000000000000..0f15f34f2883c4b4360fc871d7105309f1533282 GIT binary patch literal 403 zcmV;E0c`$>P)@|4`Xj5kLT%`al?B=W5I`&prl$WjwHQRjfmQ&G0jUOA z@&|Dug_Rm`2Y251|$~)1M2@@6mI}!8O6olw6y^Q z5X--d7nzS8`+x5q12kBmVFD!~j6c5_fMKno0(1^Q0I>i=is|LjXX40RRttS6cG0UZ?;7002ovPDHLkV1fxUnjZiF literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/au.png b/base/resources.pk3dir/gfx/flags16/au.png new file mode 100755 index 0000000000000000000000000000000000000000..a01389a745d51e16b01a9dc0a707572564a17625 GIT binary patch literal 673 zcmV;S0$%-zP)>fJ3En$GhGS>sbE%%m3$AD)q?8M9y>88-}kR7#RKlk!P~Y_PLuF7~U~3`~nC7 zF#yj00ZUDdpLsm{7ajP|&HwoK0Usg|6%f4L_{`Mi{rvv-`ukf=Ed&Gs-sA7L!Q7*a zj{*QO0M7pb%?Sw^g@yy{>ihEY{`vU@3=8@G0rvO$i3mOL`~mv-`W+b$Mmr&io5dg< z5v!7q0*L95jt`TzK8Kd(Utv)OSp_aLv){6ccV+Z`{Q2+asKUU&aO3`Kpz6wW8wp`< z28M3{0mSqnB#A*-c*8%1=RD#sSOwMznKA3=e&iEzwo{cA=PgXK`2OQ}gqId83!|%* zA_Kz@fB*n70M7pdECCwp4H&@R`1|(w-}M5x*74i)0}%fAt;XafA{48))#>Z>?CD#}*e}Ret0tl$#*RMZ7}Jl7Z|M45`5*URzH9L z{rmSnPy;{!u>dsyO%meg+00000NkvXX Hu0mjfN{&}S literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/aw.png b/base/resources.pk3dir/gfx/flags16/aw.png new file mode 100755 index 0000000000000000000000000000000000000000..a3579c2d621069c8128d7cf16440d5e45a3ab3cd GIT binary patch literal 524 zcmV+n0`vWeP)^}0h@W9fA9JOn#opKkr#VO<{LPm{QLg}EdH3Vb1Zzpp zqiZ+XNBm%5{`ViKi{bCTe}Dh~2a+HyfB%6Q|9}7eKVjxEfB<6Q<6r}-{{7;G=hB{; zLB+p+|Ni^;|DXT={s75;AoBO$f4@PDf8sps4FCQC1Q64wUw^h*hy4HZXO3U)@85qw zD*pci8U|DWQu_BVi2MUWKoOv;00M{w=;|*lY_o%kegGx^{`&*A{SSok_usF-P)oof z|A86+0*K|;FQAM6fB*FtoEI&bZG5mq328#as{}<$F zWDQ{Ffz1MH001phxCBNdC_2H6U$AI~GQbEJqg*Ti0R{kQ(yH?TRrCY^ O0000^@RCwBA zRL|V|7QjV)*ul;Rlceqc6W0{`~_8AeMg& z|LUXE8U8c=`}dziv6P|mEu%JjM}pqh@65md|Ni~w->=_)fBgZXe?Nc!ot?WGAOHX{ z0M7pe`uG9>{{ZXo`u+d?{`u+u=j#9V2j%Sc^797z|N8p+{rLO+`TP9&`u!FW2mk>3 z0#G;xDFDDQ2vg|)-@5Zw?JVTrAxNs~5&|AZ;5uWfQ`vUsMGm`>aGWoI7=P|oW>%~E z|Kk8dq@aG@HzdsB>fj@shYzX-a%=q<(frSYmfLIv5{HbzQ${~M_P_y6C&m>3uU0*DFd0+8#0#Gk)^|NLQBRAyCBeB9H+Wn{=Mr@*PJ_ZKV< zB>w@GFfafF5Ks>TBP0ZV{bBt5_ve*sKkwd`OiO#eX6=u=cfX!E#rX3NBT(umNC7Yu z0Ro8S7X#4ce?Xr63$phg)Bk64X8r&5``_O`AFf^jc>p5y?+^38KVKLa00M}`wU!~x z=I_1Fe}Df4D*yZI@1I|PfBgnRptt`0`2{iqMpRNPo|?TW>MPOFW(r1_!xlT-yep5|G*@e%^SFxf#DC32@n7=0M7pe00011 zNe=7o{FIuhzQ(sjF~t7>`T+s_0sj00{`>*}`~Uy^|Ni?^Z7Tcx|FW0O0tlpm;s5{T z+df{s^E1rDZN;v4VP>0|8GkY`{`&t1s2YfV{r~st=KUYCl59Xr00M{!Xv@F<41fPH zoWA^R$>xvtF5yd$xc~X{7o-}f=ig7DY9RXc``_>1K-c{N2q2&ahQEIq{`~z1RCDs; zw*~7zIJ!sAKj8J}&!7K)enC|K{|nUc|Mwq|27mwp*#K1f8;Jh=2byv8+}GKw-@AGz z%-rMu^XK3HKtBLA{Qvdq*I%FsKn(x^1k&&qY(LP_Uw?q)|3jz0PF?=a(?4bU?qHzN z5I+E=z&88?2q2IKpz*){`~&I%+VJc5-=Dw#?LYB#!lHLRL7BZ8-NZ5x*TXaKmf6TZ20qEQj`^F;~x-W z05U+*fBxNj@_W(7kJ(ujGnWgh$g%(Z2hso#K#U9wI~hQ+`3Dk_7z`j1tL#*2FTcgW f@C+EF009O7>dRn2w6d?H00000NkvXXu0mjfueTzu literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/bb.png b/base/resources.pk3dir/gfx/flags16/bb.png new file mode 100755 index 0000000000000000000000000000000000000000..0df19c71d20d7fdc06e1cba01028983439b2bdae GIT binary patch literal 585 zcmV-P0=E5$P) zj51&U|NhG$_=oZTA7 z0mJ{l|Ns2{|Nr-Y#^3*c{=WU_!>_-;fvROCxPdkR1P~M0Xa=C_KR`47{sXG+pY!Yf zqu=)*{%)W0>;M0szkdJy_507SKYxDz`3KYh5I`&-cY{^``2$3Z|NsB`^ZWO@y}$qd z{r%_nFQBC$4Is{6hz5WF0@(mI8^j0N`~Tl>LzQ1Ye}a&q>MtPo*RQ`|OMu4x1!@2Y zAfSdne}TsT{`c$8-(P?J0c~)w`~?J`zx?#Dg*yp^z&88=2q2IKpt(TRKniTbum8-y z1bBWi0e#F0wgIH{FVJ|Pxj-8L0tgsNfByUdJMs7b-@h3^8h-!E3i%CU{QCW$1*GB6 ze~`2PfHeF82q2&aU>N+96yg32bmdP5238q{|Gydk0=52OVEN6!@<&OA7Z~7wL16>b z@DCt>7#SFn85mf=5eY;LZ#OUe_l@D-2Zn#Y82<4v{9|E|jkRQ8_`$&N0jL_N03g5s XX0T^_9W~6o00000NkvXXu0mjfXpthO literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/bd.png b/base/resources.pk3dir/gfx/flags16/bd.png new file mode 100755 index 0000000000000000000000000000000000000000..076a8bf87c0cedcce47099c6b74b59f2c9d1dbce GIT binary patch literal 504 zcmVCcfPV}OzZe+)fYC1)`hmpw%>WR9L@~Dk00x0r!@5ksR;+hV0>ZLfIcBS@orh;x zv}95za5W)x_7^}bV3YqpdH?h;NZnuSC%?V#{+0gl`~RQckJx{&l>NO~;@7XgzkdJz zEh{VwR0LSuiyWGR{aKQ z00-R5+27mwp+3@G@Um)kt zzdstU{yWl9SIB_0ft3II3)BD*KrA2|{``^Tm;4PDy`=a1tTre>fEI#8 u{{2z<2NVVaum*qtVq}m+iAaI~Aiw~?reC_kVQV=60000gsB+3J~Dn`pdxgmx19A{hgns>oXkhsL8>j&wfIu2Rsv+R_ zAB5T1GyoL?1Q1BWpFe+p|Nf1n;TJ-~Kd@?uhChFRHUI<=#0HS!U%!8$YJib28yLY( z0tg_G2B7i3e*FSj@aq@44gY_`jRywQ69xu=0D?FP=vyd&x*M*V6|CV8P{Uu4OBfgc z0tjNmA4y3`us8lPG6H?}8%zRafgb(Cp!5f*6oP{xAq} rF#LPR@IoIX4%E%Yz;K6w0U*EtuUcjA`-_J300000NkvXXu0mjf+>pV; literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/bf.png b/base/resources.pk3dir/gfx/flags16/bf.png new file mode 100755 index 0000000000000000000000000000000000000000..ab5ce8fe1237a18d6809a5570024eb108cb14a3e GIT binary patch literal 497 zcmV@|4`Xj5kLT%`al?B=W5I`(ov;U*021-Lr1*!W5(gW7O z@cTDV13&<=05Ky_HBiN$KMcQt819e>gHP`g_|Np;&&;0(C^$RHS>olZ*Q41X9v27}ar6#W9}0h{^{OajIK0?h(y z_zOe~zZd`lhy{p$|NA4!EeST}?;nUxkP49VfMx;1;V%&U|N9rH;SU2q05LM8GXV8K n(H~UyA0);fa6B_H00bBSQ>$p&WfB*UmB!B(-`wPhZ^#?@C^U5EbbPyl_g=3Hc01Sh${{P9=HB%4| z34*<3-m=C?^;L%miR{xQv2*hU;8+Y&0Dxf-W~KjsusWFAC4@j0#9_j;X5z6SjRhH> zd}sd(7FPhVFdSi!*Zj@;_Sc`kfByUdk|3A-`STmZ_yb~qxIp9o{E-p)bLt=iKmf7) z+|Ix(`{&<1pm88mK&}8g1WG~}e||Ik`OB#Cw~m1UAb?na(Zlrn4}+v6P!1@{@CT$5 z&-#|8y{IY2iKmf5omHz(^qAp)ym^JhN+jk7Vet{H$(Z8=>|AV=V zva&!M00M{!p&AHub^kXuF^G#pRQ&(-8^nMkpk@XJfB<6o_wOIv5C1P;X6Wwu|KUB< zc%X*g2-OTg#J~U$KumBafq;(A|A`a+OH08N{X($;=pP0KfB<5Fs|GR7oM!0i{{QYB zSm|$=!=N@Wf}I2qKuka<{f7YtBjf)QCj1u{`~UM7nrdKh0c`*VF+c!8{Q&j%sZ;-Z zd;dRshENS5{{S`og~Sg)05QIL^-54s5b7kL(8GuS8yfz9{>%Ui`+q-vfW*P*^_43C z0mK4S`s2qBh&}(NP5W0_$$%QQ@R)`GfB*vkck5Jby^kNv00000NkvXXu0mjfy0pt~ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/bi.png b/base/resources.pk3dir/gfx/flags16/bi.png new file mode 100755 index 0000000000000000000000000000000000000000..5cc2e30cfc47452d5bef949628e955a522d59e50 GIT binary patch literal 675 zcmV;U0$lxxP)$wbBBJ zMTk#;k4<3e#ePFE;{?TciOx=-NpIdg`t|#dcz^$YFqm+of7AU<7UGr+0t^5F#PsJM z(2)${Jd)SmT+KY5@!|h>po)L5-!r~>3uJux|0`&Jz~QGy6a*CiGyVtq1|Wc#zWw|0 z_y6C2|NnAvaR2)A>-NX%|3Ci{R?!hvH~jzU``ypCK7Rkq&&~h)FDNvCApj5nF#yj0 z0_X_*{{Q{_|NQXv@Av-qBMmR$teo!O*6-%u-J+8r3n~2s`s?uP{Qmp>{`~+900M{! zNC9;}eE(3IS9-C{62AZc<>Jx>%af}0@?r&05Jg0 z{{#T;0Os`NWh`ko4>SM%|Kw(60099Kad7|t0qcf^`tR-^sIP`Fhru7lkI#w#>Hq?W zkzqQ+@08y_|9v}t;{CEE%)%nTc=-MC@P)7S@!~g$((Ud|+28Q224FCZIGXF0FQ1zcbfB*dX_lJRr z;s3wCNa|2D02KoSAbE^!0Dxf-mZ69ApkCb5fP^9ydGO$cm6w`kGj(t#`M{tFlLo%j z*4%mm2&CaJSn02SzkrtfWBLcO;r%bLy5Gnoqrh)qC;VKmZT`F#yj00W%wG zw4zx17##T6*Z=hN0Tvey7!|wG?K;V)0{r{_`}_X<{Qmp<|NQ*_`}@YSvI2-@&cAgG z*R?p0?_>V(@&EVlEP?{x|1esA`||VNU68t8zyJRJ_3zg&hTp&0WMzR?0R#}s1|E|% zRV}tRkH6o2#3;(nsVMXI-pgBmh17ms`TzTu!pfBl%*_9R;OEbWDJei#0R#}sGpDd$ z96Spi@~bn7G5z{~^_!ZLy2#s;5B~o8&G`G*|6f0Ap0WS=_rFd2C(ubi4FCZEF#yj0 z1a!1=2e0}MwgDi3SU@2S4mePl{012eQ4J-3 z|Mm`933BS6zyJRJ1;ztF0D(08|NVzmQWB*4&)@%$um=Y`lmy1W-@hDx{{qQh3=9AP x#JH7#;TJ3-|G=X54_FW_j)5c_0|P*S0RT0dOSD~(4;cUe002ovPDHLkV1hfJDkcB` literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/bn.png b/base/resources.pk3dir/gfx/flags16/bn.png new file mode 100755 index 0000000000000000000000000000000000000000..8fb09849e9b5712e9cdd8a2c25035da201535cf5 GIT binary patch literal 639 zcmV-_0)YLAP)8n_8%|dG+hlCr-g% z|9<~wU<9iE{r}%DMphZ1Jpcj3%*DZBWo-@72DFWlk(-gj@!ngb-$#D&C_i9e{QvLY zw|{?r|NHlgiHY~?^IHG`05Jg0{{(k=dF}7->+9=cXlNG}79t%T{rC3_t(pA#`tSX# z4jKOh|NsB|;rr`({{a5__y7Wk5omBxQSrlv5B>nb??0VZ8qCZrpS+?}gatn>o%-+B zPl=+||6st##PspQ2Y>)#{Cu5(QJ~_^?faD-pMV;E|7MwLubjQ@B-gLso$mVYgECpU zxpfp2fEt*XnBKpC4-fz`0M7pb@zVeZ8g>5r-~k2r`Sbhd;{WmN02I(80QmHEv)Ik{ z>H7Nm`}_MdF)?FhWi>T50*LYBMFw`s0-y$le?J(QfB$Fr_2c8e-`_!j`0PG|ckZ*_ zzkY$-`sc5Tips@{7Xbo@1sGC5IYwrQfB%2{|MTZR!ygX*-%McG4cZmTY ZzyK0(F$K@T-Dv;-002ovPDHLkV1la=J3;^e literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/bo.png b/base/resources.pk3dir/gfx/flags16/bo.png new file mode 100755 index 0000000000000000000000000000000000000000..ce7ba522aa7e948d581478432643c230eed1a658 GIT binary patch literal 500 zcmV^3LvnC{|x`%yaFl$ss8ha0V@6XKS=c-5cwO(_{}IL0ki=i zfLOjo{AE-9^-mn=h(G`Tfz|!{{r?|W+uz?{^yeR#!Nm9NlRN`J0I_^YV&Ikj@%Q)F z|Ns9m{0FN3^Z!3k!*8HnFvf4N5xas50L!z?-wXsAPk7$ ze<1l+iQ((fPYeJ7#KQ200VpKFA^{3Nph^G!{9^b86oDW}(Ek1R7ZiL9e}Ret0*H}e qBRB&8AR!3%7c6cef(%d+Aiw~vBYd|xMihYn0000j-HAXl7XJGjM{~r+i{r~sxzrQwG-&h#_Y&p;L z=ieV7_s^f-zyJOD{rC5(+EoAn1k&)I;s3Kw&;LT?{{2}P{Pq8T&j0^^J4?LvUd;UK z&+k8ffB*XXONL(tXahh1fi?X94^$0Q>Z$uRRO)Y4)uapmB!2(-ul(c1=C+V!kAF`) z$PCo;`_FHns{jIs3Fu;wy-Z(c2YwAz{&V4aXk?bejFO*Op&u`@i~PecqBpL@DIoojb8mb+WHGK%fG2>)a3=iVf_~v+`s?*1;!`?Kmai^I3i*ZIYtpN f{g(k500bBS@Ns{bTs^2gCr95H^s6Fo1}O2_S$Nfl}4;<}o-r{^R8Q_xtzX z|Nnu?|Ni^;2gm@D3=F@4EC#P1& zzuV{ie)#0qf2Lnh)j(~3VeG$ufPMl9Aczeh3x56n#l!R`HRQLfpFjVwfkN;%I39k( zVgne^e?jDThF>oL0*Hk{T6(^^8pGqq44*zhqZ1OZzkZ>_F(mFeH~<0+0A4S6=>Lb* QN&o-=07*qoM6N<$f&=*Yr2qf` literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/bt.png b/base/resources.pk3dir/gfx/flags16/bt.png new file mode 100755 index 0000000000000000000000000000000000000000..1d512dfff42db1ea3e7c59fa7dd69319e789ee12 GIT binary patch literal 631 zcmV--0*L*IP)?&DC3JV7l?ccjcgB=Qq4l4w|Q;eOZ4z|IjsEI`#PYSloM|AFHF zfy)2>XZQ=$@t;lU|F1tRzpnmg{PUOLH{-8A|F{4CvUU?d0I>k|0TuuM^_1cNUy$nm zzZn?*{^!*ACzSEy$NyhHzB0Wn`TXRU=!%=n%Ci4h82|!^32gR%glZtk^6USnb00o@ z{`LDW>%U)&BK_|-y-75RkKVi&O=|xC<=6keK+72b0*D2q;Xlai|Ns9mF#h@fM(h;aV>^!x1-zNu02XV-n@ zm3imZ@&EI0hChG)|NZlafdL?Zn1I0yH26P<=DUx29QQsc%}izF;QV-S-hYOl|1V4z zX|a-<=Kf#g*Z)7i{{y|szyJ_HEKEEM|C#>$KmJzoZa)M2-~Wm-e7Cl+vi)L|kY`}} z&A$F20RV*|BkB*O Rz6SsR002ovPDHLkV1m;fPLlut literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/bv.png b/base/resources.pk3dir/gfx/flags16/bv.png new file mode 100755 index 0000000000000000000000000000000000000000..160b6b5b79db15e623fa55e5774e5d160b933180 GIT binary patch literal 512 zcmV+b0{{JqP)O=a{vExMP2%`MCSoB^FIcLe_%lf;|~%E5I`(IQNh}3Ao>6Q|DFUXMn*>AqQd`w z|1kXd^B;tM|Njjl{{hM0zwd6?1Q0+hV1xeud-4=Wy?p-%sO`^#2S61Jzk!N?s)6X& zzhA%p|N6}=D+{y%Ab`Lc{sL9~1=0UN4*CD*7s%9KAf+JHKs~=eB-8KTKvw|-5R1&; zzd&a|ob(5%^Z$Q=wHy9p13+aOpFRNu5F>N&`Tk_-7w>=n{RejQzkfh&Kn{rf10?_b z{tFTZibx5v&dxav5I~H7|Ney-|DWN1$%1FyagzUW0464;_wU~W1Q5$TW@eGxtUvee z3vAf*8|igK9~@*rr66bh|NrkNM8z+V zAV?>O@ek;bKfu6d00k6 zPW&$KB`I@TtA?2x@Q~7pdcWi#1>DDZ2>MuG0I@IumHuaV^&7|soAMvT0IK){RtF@1 zgH;3B;_Qq-34j1%{P^)BFE1~|NkA(gBv!!4$aw$$eSiRB1ga=2D|__l(H|iA4T2Ex z>lc`SQ9x2&UjE?0g8%`<0`lvhzd$}*14J4{IhY2@0~G@V5J82%q9;EBlXu0U&@_82I`BfBC|Yn~P8llm?myQ3_K18=`^X_ivyEfB<6p_xd%%#*GZ! z-C&_V5IGPDK|g;X*gypg3;+Sd!XPTj0Q7fK5>&$Y{sHB| zjK9DB00sa3QR4q|tc?L6fSCSm+3>HW`NxbYpP7GsX8sK%KS9yYPfWi)GJ)AFzdp14 z{>t>1fsFwmfLQ*Ci!yxq#8guv=_mQ;-(Rp{AoSPbXFRCwBA z{KboB21 z`ppP*BG3|`!vO*asNvt=e_;3gWsp&PA@E<2jYs6ilRy6-zmSku5?~OOP=5aV@4sI_ zSN#QP00zQ!JD>SpAKYgR_QStF|9~F;2M|Ck zz%U1e+FyoWe;B_0VVclq;}vp_kNy3hKMWrj7*{kqJbMcaQ;_Pve;I)x1Q0+h46j}> zeiN4E1lkA+>|e|*mzJsW^M3)l^W_^hf&c&c`Mv->`48yHFF-%s0|+3-*GLfwiRNz% m3}3(u4lrUsie?}H2rvLBbQv(L;??y40000e`b1WGV} ze#gbd^&bp=ef-GykAYc$@BhDltSqdeSy?RXJpcawy+5fJAb?mHcsPJ&{d@EF@4HtJ z)qno||1xd*zaM|Ot4f#|8A1AQ-~Pubz$7IBv;-i4SQvovfB*ge{fFVtAE4aNE7yPi z`^Eg=5yP(^Ur(Q5`TLjM%#`8#_rHuB|9}1hItd_vSpNO`#qjs<|KGp=|NIHm@MXqK z79K7}ZvOwQ9Df%s{`~lX*xI%KzW-!k{Lc96Cr|@G0I@Lq`0?-epMSr9|NHeD?&umBG}6iH(DSogJte zDERNk_kV0Zng09%Itd_vSb&=T{rt@+B*66dJ0my{fpNkvBm!jpV_;xnVgd@XDk?Dx zh=IJyzyJ_HjJJUrz)|>#fr0nRl^;KTz#|yK`2G9$BS%LzureS32rvK^u`=B;c)+&+ O0000d94tALrX!Wj0S6V-v9sr07*qoM6N<$f?*uARsaA1 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/cc.png b/base/resources.pk3dir/gfx/flags16/cc.png new file mode 100755 index 0000000000000000000000000000000000000000..aed3d3b4e4467c33717ab3e2f61596e06113f9bb GIT binary patch literal 625 zcmV-%0*?KOP)Vbu`-)NXk-Y`p?2$B#e1 z{(buQ`}e;;zyJNd_UF(2w_nb@VUiUP2igD-Kuin_BL6vl`zgIQV*mR8|8G|2U!T7I zn`-)Ow$bxne}9LGfB5z5*XcJ*K(;aeSD>o^0st`p&i@1e@&c~g4N@7~{}B9V!5sbp z`j|K8<@Nq-&kt=P>@pAZ`T7Q#;RiPl^j;kSgdzX}05Jg0{{#R8=f>y-z~LG0`u_d< z{QLg=2?6_k)DH^)`=sFo8YTUi-v;{r`o8J{6Wj>^)c^vB2^cJY|Nnmc_5b@He}DY@ z_51JdufKoSslWR1>-W9)3`r;XfsXn0`_Fc($H!lT!V@5Xn1Igu{qOIuf50&L{qg7D z?|*(LofMGa_%_k-*{}b_0g?9mMSwvE)Bq4bEIr*1})*zF_+U)&LMdEMOb{Nb-vOh6FrNC(tkd{&4;N%g_D$&)>g> z0^hO}m?z%iIsOJ1mka;_#K>R{i_RZNQ42x8VJSe8f#Ern2@qfa%&RHCyvg>Q00000 LNkvXXu0mjf=TkSf literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/cd.png b/base/resources.pk3dir/gfx/flags16/cd.png new file mode 100644 index 0000000000000000000000000000000000000000..5e489424884d2ec9e429f70d69af00edf242a077 GIT binary patch literal 528 zcmV+r0`L8aP)JkPqeYl28iLgD=0{><0$P44T5yOrT$dE?(KkwMFdoG^-J zGv9P)Kk|i5`lcNgUUAbboca5{hI)v&h!9!~`Yg)Ld}$VwYqqXn@gVLi>3LSVGm1W? z3qnDJAk6chH(u7f~FohUBCxfQDx8?5BQsCcprAnfVhO SHC~zk0000@|NZ~|iEi8i zh~?j3h8^dV0y&$fY|i?}`2XK;hJSzm|G$6#|L@;V)&KqZ3sU;$?>`_ZF38C6g#jRd z7@s_ODJ3Nev=9gw8UKSQhX4P)z5oCE{eQ>y|1j|H-+x9%#`EXT0R#{W1H*5i5@u$g zs{agN2m-%;fixfipeaCQpFe*F2q2cU!)f`}`5%6M06O*WzrTN({{8*;CkCkD_wPBk z=llWket~@P=ieVecEOTuB>(}$vTge|RYlbYUmpDW_v_E!KfnL|{{8n?G|>28zowm@ z_UrGj-+zAtrGTUoztWctUjPD#h2amw@BhDn5OHz(52cFPg zot=T34qlT?57Mzkg5?0ssOG0Ftp>paW8OyZ`_I07*qoM6N<$f+2k} AjsO4v literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/cg.png b/base/resources.pk3dir/gfx/flags16/cg.png new file mode 100755 index 0000000000000000000000000000000000000000..a859792ef32a02b41503b5ab5f216191af397e02 GIT binary patch literal 521 zcmV+k0`~ohP)i@P`2b{=v9^Ktp0uZ001fLMSM)r!?%mH+B91 z=ii?+(ckX8zrd=&8g~5t-|*}I50LQ;KzRlRfB=Hn08;wv->)Q*Kc0LLgTdsU-~VfV z{r~#=|1XdRMzE6r0tlo5X#B6gzhXrG`18Y*0!g6iieLY~Kvgqz}`W zLWO>Z3Lv@r7+CdZpiy8Ae}EeP0z(_<2Y>)#Vfe-1#`njMUlORAfdMG=o8iiD#%aG9 z#Q!h|feZ$rzkeYJ=p=vuV)VVru?7U|?FE@Zm|i>fBlzF zc~M_qKf%h=bAcoS;}NE7f8|yFe%B9?;;8%o@BeG_!|(4qhyo=(h-XBmKHXpc{~y!A z`THH3fsDVeudko)ARzm9UL&JI!+~uEM*rBES1=kd6zV%LH0J*N$gIQAc0y}k9qTFv z4h1oVG?rB#zNY^8{QUp5wE>>R#S4NZQd1i@F)*?OF@6y}@zmk^!Gr7L9asuAf!ae1 z{{CbBBH^Az=(+fAb?mHzA!MjRs*H~|NF=I z{~td;@BjZG-hUVsqZ#w(|L@=b|NQ>{d(*K^00G3pzycQk`jp|{UxvSb;p*Vv_V?Sr z{{Q;@@3$6WKrBG#F*5vR z`2XiW&+Xo6{KsbP_-SF+DJF`pL$*;0gaz z7NKVhyo`U;4*0+SK#>rfFFfafF5DUYXKh;r+@n*scPQUy6`!63S zGXn!71H*qtMn-04W+o=4|487=moEST#KiEAA;m(3;Xgy1iO{3BKc9a12~-UM7^Z`) z1qdLZI~bN-c=z}J|D88K{QmR*&tHcBxB*ZDKmf5Ya0q<-!`is-{h$8~f7m(x{QZSX zH3Jv`1P}|uy*o^wIGI2G`1kie)4zYe_&EQ6|NftW0ohon1}3I|Z{7d|5aVBMp0ssVo0Ek~;W>Z#0SJsA+2j`G% zv|UVeYYs-#Sn6_J90h1VosR?LBU7{U1rQ6+R0f9sPrg3=`~UA>#=n0a|7Q67_y6zT zP{j57|G!`V{{zu)Mn+knB>(|98e;E17s>tTLaMG-~Y>h{r`!g0jL-tfS4HmF#P%V_xIo5zyJLP zk|2W%e*G8w^1X|KC618W{eAoCFX+EI literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/cn.png b/base/resources.pk3dir/gfx/flags16/cn.png new file mode 100755 index 0000000000000000000000000000000000000000..89144146219e6fbec7eaa89e1bf4b073d299569e GIT binary patch literal 472 zcmV;}0Vn>6P)$bmtfBa_T{rmsVufH!rO2O)W0!b+P{TrwO zAb?mv&i(NBbu;G`sX*)cv$d*%>MiL-(QdhpkjakVmyu%k;sfcNRj;yhJaxT5MTg0u5&QfH8#Bf O0000XbC_7v4G9~kE;3? z$h?1GrT>4y7{3|*{r>Zd0U&@_82$jY{AFPH^Plk#hy=QU5o|Ds0oDLyFn~2M0QE2c z1P~*G;PKK9g@-SH{rUU<_aC4k|G@~v`1Kn|{`&=C|M{yZ!G37cNq_)iVfexD=MNA8 zh5p0Hf4_c1v;p<}|Ak}_F!%rh2&CcXZ-(!`82&@8$XA^gF6?xq}zd#y5N`WeVBbyB+frxZH0- literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/cs.png b/base/resources.pk3dir/gfx/flags16/cs.png new file mode 100755 index 0000000000000000000000000000000000000000..8254790ca72f98d9e79d94bdfcb8839b1fd434ad GIT binary patch literal 439 zcmV;o0Z9IdP)|s3jQ%L{DG0k=ogG+0SLgMnA-pV!aytqt1(q3VU5g2cTadE%W~lnu`}m; z-504zOD10s2K8+~RqF^K7O;8$o;>*sR0>r0`!|sM`x~eNg#P~i_4n8BzrTI~MgGdl z@-i@d0|+1%Q&SyHO(9WHu7Cgk{{@--A8b6x2B1zb1BygNIks=N00WJ{7y^0)%zz1kWJN^&bany+5X-;o*O`wU`+x5q12BMq=+`e0f-vAB ze||Ik`OBc90(3J#0I>iAmFf2%21!Yv97q%>_xm>^i2a8FLV}HlAfRG^0AlbRVNjfdgKH->)<41fMG{Q1Z53yA)}NHF>VM86o=*Z=~EMTLRklg;&|8vY-+ zh5rBh|L@=bKM?ZoKOp1JpMQV<{rmmr|L=eQfFkpA_5cJB<7Wm2?&_*f&z|!oCH%Iq zVPN&@1^xa7gnxhi`TP6#zh6KNfByZH;9_972M|CY z4S#m*VEXjw_teQhfB)LctFzlGTKpda#8eRa1F`|=V+j!s1_l{`0AhU0z`&K2_5c3; z?|=UACdB;@3Hy%?Ffai9!1(6P8-M@;JL%7#4}bn}Wu*W1^8Nqk|9@zxfJk8Yg2Rge z5=!5G`~e6c79IwMkAMHSMfCl8%kXF6O^EHl82Alg`~}6s-@pI={`>#;Kf}J}IRF8~ zc$$I1RCFdZQi0L={}0epF!T#d{sWT?V3G+SzyRi{Q|!NXWpDrh002ovPDHLkV1m+z B7Bv6> literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/cv.png b/base/resources.pk3dir/gfx/flags16/cv.png new file mode 100755 index 0000000000000000000000000000000000000000..a63f7eaf63c028615b2ded5878b5e14a7dbe962f GIT binary patch literal 529 zcmV+s0`C2ZP)*82p^=00=`tlmIeOf&y&dk@6oT z&CV8YCOfMzZ7b-;WHc4ffO0*K`UGc#9pHKW{n=1`s=Y4`sB0UGuD|F2(+4xFrs{6A+r|Fh*S$P>SRGs(%l z+O-QHfEa)O{tdAK=ovi517(5A-n@AO5I`)f0sl(Vm><0RZzq2;(QtLuuFT6X6;y@p zb-8u)9gSFj-3}5^z@SqUX4qfA01!aT3<}j|#!Osn3@^V(zxysO&hx#~ZN`f)vS*$d zpLlA?$HBnM&cM&k$j1o^^oKjY0t65vgZ)>ehy*ei5K#*ZyWju7F%Ll?01#jRixNU5 T4U6zw00000NkvXXu0mjf>cZT~ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/cx.png b/base/resources.pk3dir/gfx/flags16/cx.png new file mode 100755 index 0000000000000000000000000000000000000000..48e31adbf4cc0074f40e95f87c1f103b91fe270e GIT binary patch literal 608 zcmV-m0-ybfP)Uz~~Q*L}q{yKmai^Fs!d`Rbj9@@=xl~KZbvQ|NZ^*|L@=bfBpc` zKOp-38^rz{DEepVv)`L`Yyt=%76t}3hHqR?<~aN{I`!9n&u`}MKs~?z|Ni|Cihlk3 z1w?Q7fI4M?HUI<=3&<7!82Y{{Q;@?^mDN?|=V) z{r~^ll=rtu5CcE}F#**BRkyY(adR>Mc_H{~T5^XRV~oVFSgBv#s=t2z{grn0SJIVV z|Ni~D^5u8)5(a<(0%_pmV<{@S{pr)+Nt0E6|KyV7{&xHKulY}Z0S*2Ic2cIyuhSoY z&3*a@=p=vu0%~ALNs$10lZEA9e*W!WzkWV{%9A7hYlh}ewm<)V{rd@2{rBIm&Idr} z{RV0P2mmnv&i?}d08{q%2kh+oUtbt0DGA2L@2{yn^Xv%Q%_4hjZ2Q{KfBuh*0fWjOcoPYi>{Qk`ejtlm`TPy!Q@c0|K1n4Ay00P>u ul!4(JQe+}W>@P40kp+Sq42=5$0t^6?P(4CrvcmZQ0000s1`2Y9I{~ve$KWO@Yukru?KTxgz{s9CK3*7Y} zZC_6Qf4TJkuQ&gHzW)Di+kXz$|9k=eg(Cm|XMz~|=g%L20Ahjo4`KiVr|y5|U;qEV z`p@?NKb!P_9;^R?@o<+hfSm*oKp+h;f&YIQ*bg)L>I;A4WVP82*P-nR{;Wu@%{Vvyu7@~4txIf`R>OD+-01E zIfRil07L2S-Mat*#Q65@TRuKMWMi;}EJy%|ff@h;2;_%%@7_UT@edf{0+7H22rvMY Ws9gjvbyTka0000? z0048MLcfb{@Lpld*gfdL?Z zSQvhRtN^J#x6%GQNHxSfxHgc;AD{-1tAIKH0tl!9q}uD*5!1Kl8Kk6va!f$;fJ%WL z`2Cv^NdEc54D$xi27mx!VfgXqT8ME7!~2)OPy-`SXu#NiAkhzFFflLy1Q-A_8F>@M S6G{sJ0000h<6BFn%a z@b8~2SoNP@zd$;E{sbbRuHQd?{QCI=sNwhbA3*&Qe}GP900=;09NYi^fU@pUdVa9*13;+Sd!tjgXKhXQEMobL97(p6<{RLvMGBN!7 j!N9=G@a-1^K!5=NcXWu!7_DDe00000NkvXXu0mjfeQx^H literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/dj.png b/base/resources.pk3dir/gfx/flags16/dj.png new file mode 100755 index 0000000000000000000000000000000000000000..582af364f8a9cb680628beae33cc9a2dbe0559f4 GIT binary patch literal 572 zcmV-C0>k}@P);we;9uK`S<6~zaM{qBL9B<0yBR7V`E_e2q4D) z|Nnpa!Ep64!{fLA8NdLj;oraifB*mg`;Xx-kn#6Fhzn-q&in!pKrBENJRA&WD*ySo z7*5@0`26EP69WTC_22)0z>5C-g{l_hVFa245I`UeKudt6h7^Mc@BgDW81BCO4-x~L z`sXhc{R3+I%fRsKA3y*x{R6rHsA1>M|6jifb2E4w{z{xB{`~z5CPC;Y7bk|9<`c2PXgjR$^CT@Hzz$KrBEfF#?VC z^aSdB^z+g5SJMxCJOGqNsQwQkfr0#&=?~CJ009Kjz|71H^!MIRd#Ajb^76;aUyQ$y z%m(TN#spBq-#`C>zGeUjAdrR+|30kwu=eoBL!3-pGMq9%bs!`E|ACMovw

4;Zk2 z8GbPU1Q5%#7t@Nb6*GKbU;u{yA29j{CVzn$|6qa)V3LCYAiw~8(_SNKujRx50000< KMNUMnLSTY(1rd4x literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/dk.png b/base/resources.pk3dir/gfx/flags16/dk.png new file mode 100755 index 0000000000000000000000000000000000000000..e2993d3c59ae78855f777c158a6aae6c1fb5c843 GIT binary patch literal 495 zcmVh!ZNvLM`<}kPiIA3?K?Zl!VJuS0ABN12uI2v;s z000mK68GQM4oDR3?|C6;zBc4LR82Q1eETXSa+3nD0Ad8%4|Ml`Fn}2U{~ypshW{9V zk%{T!hYtV&#KHiVV*o?2zW>+&Bgm+K00G4EikX==E9>w5`yf~S`o*<00G4K6dZ++hy)_Bw{QPEdi2K7 l5H1Kw2asrHVqgFWFaQRwS@oh;XP^K8002ovPDHLkV1foV*8Tth literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/dm.png b/base/resources.pk3dir/gfx/flags16/dm.png new file mode 100755 index 0000000000000000000000000000000000000000..5fbffcba3cb0f20016c9717614127b89db4c9664 GIT binary patch literal 620 zcmV-y0+aoTP)yt}{r~U(pZ|aU z{rk@#!dhJXj+vP`D&$&!2yPR?Jud5I`&tqo00z_V3?cpb$_)%#~li z5Bw?p&G@T5&5h~tB<;UIJ-`3_mgbQL+5iwhOdtm^{QZlh+Tg>NcGo{qR#UR9ewx4g zlzHy^uRp(j{rmOj?;oHBfB*n70M7pb{ow!s5r+W$=Kufw0RQ~_o$a1N^GPoTT-yiw z&XGVBSbe$r0&xrf|M~#~9P-zx0st`p&i?@b004Y@cH`sX`~3X;`}>j`1PlZ1WGkKd zF1~FN+w&9T}cJeJULy4V8r?0tNHM6WN&<2126ppbC05A-~q$vMCOd&N)3^rn&3WaiZo>@dB zxpL5=L>h@#UjVT%{Q39iA58Ths0J3s|NohoLF&Lt!8(8c18V>XAjZFc|1vT%{s#lF z^Kb%2CZ>-cJ^%y|<6Q;@;r#qR4;}z*|Nr|B$h_ab1b6QI%fu2>dIV_O?>~RRu82tM4=f|&Ke}8;oX5+eBw}y?G6)5=s|Nnnr@aNATAPEpaEN{Mj=m^OD z&%p5S|G&Tg{{H#<7bL;LEGj9<&cFmz{_j5mJbLs9Ab?m{m{|TZ{D1lB9Z2clKfnI{ z`ThHs^2c9)q;CF`l>Eoa3N#g>nv07INCE^93jWH3lKe}28-VENu!{qxMpm&svFOiawo%#4hT5U&FS z5Yzu(KY%Xz`RDh~-yl6N|NT~b@qz9A2lm1$Hf43G`D-AmnZXVNY5)izCWas1fbRMA z8?52ykLBVV-&q+tkKFpbbOC=r`2SzOfQo=l0_p*hfB*gk2q2IKpzD7Eo%H+Hk6%A8 za57|Q3rv;f;d1r)FDv_xg9F*eKs^8f#KQ37)2~0jMR){${rwHH2k3S7pO3`Z{#jf7 z{|`16Y&=9YkOT-IMh0&|hF9+yelRe6V}O#tcxPkSx96}BCoe=1&?OKCkOT-Y05IoG U$(*n^qyPW_07*qoM6N<$f?|9Y@c;k- literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/ec.png b/base/resources.pk3dir/gfx/flags16/ec.png new file mode 100755 index 0000000000000000000000000000000000000000..0caa0b1e785295d003869330fc4e073dce07e7f6 GIT binary patch literal 500 zcmV1sCzZm}g`N!}J$oTi?|G$4gL7*^D3`7C}Kmf5Y{CmeN)&f@km*M|^ zrvE_l-~a!AA&BAspa1{=fXIJ9!9O2vbOQts3j+fX{b%^|8m0my0Yd-4N`WN9@BjaR z=no^SIM8~400P%s(0a|A0FHhM?*o#se9Q zEZ;b|7ytr@MWm#zEz$bb`!9d~{{Q>$@1MW_!07MqKOpw+zkh)g(B$8L|49h*Ov!x= z5I`*NZ%IAX?Fbu$UUAQCA3`wxix_2=I& zAouq_SzðCcuS!~%52Kai0?gF&VORsRAR2~rJG2PFT1^!)w@)C_d-AAkU2Vc75Z z*R<@y`9z1vevIh)-p7{p`5C+7f|6l;f1_&?! X)GmJPc-xs)00000NkvXXu0mjfGFPrC literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/eg.png b/base/resources.pk3dir/gfx/flags16/eg.png new file mode 100755 index 0000000000000000000000000000000000000000..8a3f7a10b5757b006948ea4436fb242d02dc9a4e GIT binary patch literal 465 zcmV;?0WSWDP)LAHVtk{r`=k{y)(2e*gi*sIRYISXlV_^=qKp{(!;n-+xj9 zUjemETFMXP0$m6sfwJP_;%#kh009JYeOg-Dy?gh5gTXH_fG|KLm<2Qhs6|CZ<>JMQ z009IFR-loRl9E6vpeV=!FaTTi8)D~Q7yv2;2q2OXK!5=N{?|@pNV(X=00000NkvXX Hu0mjfG@sA` literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/eh.png b/base/resources.pk3dir/gfx/flags16/eh.png new file mode 100755 index 0000000000000000000000000000000000000000..90a1195b47a6f12c70d06cb0bd0e4ea88d7bfb03 GIT binary patch literal 508 zcmV`hKmn*~pz%QT=MPXRKmaj;?1ifa0xhloNlE|L zuK&--1mwx?-uoV+`qwW8u#*4+i1F_GyFwg7fByafIr{%Uh)$p>Ae%w(|Nq~=m~|`# z{`_H7QhIal96$iEC^sml1*F~kc<(nb4FCQ91q_kDz!3TkBLDsd`Sky<|4qNomi`s~ z`xoeVfB<3v8uI)9A4wibp!A=AfB%5B0nwj-e?TNKsQ>@@`|oeijK3Q@{{o!^5I~F! y*$fQd7#Mzm(H|HCnf(WhfND7yc3x%x2rvM-AWsdQI)rrq0000&KpNnxA)<^73~VwoKqoOWF#%15i9uxn0tlqx)vH&?arx`ryF**H{9<5mxO9m@ mNC@PFfB*h~9RdUZ0R{j9;Y1$IN+(bN0000&(jx%j7OGE_~DVuFcQkgj@33fJv($pjj zgoNxWFM>pG#K4X+%S_Ys!f>f$mib36%ekHNec$;y5njB{!+Y`YzVGwA&4mTVh%ikU z03gD2Hn&LPeNu%hDG7PUvzrphs|^(-as$IIo1LmPya%Hc0Qn*6qc4XX3oKoa+Z)_XBQk8 znPA)XelBh#6J<)fj|w>7X+~Yun^@Bp4$+N z6L8rb{%QnJN{fql*fJH1L*2YjUlB~CXS&&LY)1V3h&68|x1_5-(4l3HUgs~3JvLXI z$_D=zL{dTnq9RK`-w~w|sCYqqA;@OoAE0!{9Gi+cF%zA>5*8OAiXWs z!A~!@Tb_6WJ;mn(q~>CYJ~Oq(|Mc`miY)G1d$)?S_lf*=dz3nd-8+hwz5w#U=!7L- z+Ve0W8Werm#o=KvYxRVVNtM9!poHk%m;Y{gxKdXC|Y{ fc0^aUlspXz7vm>S7OoCUZUIwXLGJ6E%Z+~lY(hhH literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/es.png b/base/resources.pk3dir/gfx/flags16/es.png new file mode 100755 index 0000000000000000000000000000000000000000..c2de2d7111e3cb59cf6511dd2ab045e824bdb43e GIT binary patch literal 469 zcmV;`0V@89P)@|4`Xj5kLT%`al?B=W5I`&pe;NKW0^Ri&h`xRJ_x;0v zUa?=y?0^3M|NZ~}FE9c#{{3cP{Qd6}13&;Vf!z&M{pZWqKYu4MFm$tgedF}w=P#IQ z7-9gT-$11R0mKA$(qEu4%ok$*y!^wMRm*x;`R7|k6yu?K{s8?55I{^|9{?Tjhec2I zv+6&FhFWG_BbNVc|Ns94tNRJp!0`V!Py;{!F#$2enB#XZaohg-5%Tlk#oa&nzQW9g zl0Y{D4gK?n0U&@Fe=;yIr=|V7caH%YEYL84k`Tt9-wc2LGODP&y?7BIfLMT@X8Qey zK~fSFpuiXa$^kk7RCwBA zWQbH``0|MX0{;DB`1Ob3-!Fz=zZw28fY1*HhF@R=VQ?@21P}|ur+3w` z_wT=dfByab`{x&s{PXYspTB>919^Y{{Qd`I{N9v10U&@_7=ExZ{APUe{`KE~Al1MB z{rb!Jhml3<_uqeCzux)%bv7|NkFAvw@aK@N+YWG5`bsF#yj00sZ{|0ReUZ0OJ4u`~d&_lgxzd z_7grGtKje;)ax=32IqJ>VE_O6|Nr{|0Uz@6!2*a0?AgCSJ_s@V{`!jztXlEUzkg2h zOW%AK0ILQg2A~)NKmdU>0L=y=29PKt(~s@sMWK)O87MU|4G0ImPt*+y7s`{{I1L_{;G9FVHyv z0R+;(^!pEkq$JpwzYKqVGyVRp{reTr#sB4{{{Q&{G@Ah!GGGK$3=lw!Ux87Egcwk{ eXi`7`5MTfy3O%OUuKb?>0000W@Y84;!#FdBh{DWNV{85G^eR=U#)*62qRvoaLX5p!7Lm^{g>IM$Q zMs{Q_?l?+2NRuC{19iOmU$>t9;*>tnC_qaIU+T2fR7nFyd0Z0-b-MgLN zL~_)yI%8}kwU1=sY!YIJllUc_pyhtI4TcZ)*Lyi~^>58dcXu!D%H5T!AO`R!zyPR# VdiZ30KxO~{002ovPDHLkV1g_p%GUq@ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/fam.png b/base/resources.pk3dir/gfx/flags16/fam.png new file mode 100755 index 0000000000000000000000000000000000000000..cf50c759eb28b5962720aa1ce0617a29003e477d GIT binary patch literal 532 zcmV+v0_**WP)SU^I57#IKohy|#uQJDd#=|98& zUrgMLRb~JG{$u$2m+|*M=0AU#{`@s%|H#1h=ih%I`g`z86F>lpk-UOTf}FCMD80)oDIYC+&q4vMR0s0&DpH|L=c>-#`S^3sJ`m zRPz_88i@Y=|MmYr*an6_AO0`^1P}|uzkh%JGXi;k8UFtPIt#4m|G)nbm0000FP2AE)Ir2{}>qlLBSs|`Qg(SfB<4)VqlOE;Q=cD|Nnn$ zna02W|Nj1E&`=Tpav_4q;M$#E00G4E4{SI@`q`VGKvVzz{r4XmU}R+c_2(Zz0I~c7 zs`v*r?Dty(;z&PFFXX zRA5t=4x{1SIibD)Vqy6A2V^D4P_SySA|L?j2ip1XFA)9%V~_%1r~w2J3=}{2Oiu1 f7(RXZ0uW#T>&I!FfdIJb00000NkvXXu0mjfj-u42 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/fj.png b/base/resources.pk3dir/gfx/flags16/fj.png new file mode 100755 index 0000000000000000000000000000000000000000..cee998892eb316c3293ef2d52afec9218bdbbc03 GIT binary patch literal 610 zcmV-o0-gPdP)2C05Lr?a%1G+Sb3M_ z-f!*)-&mJ@lxC7weD@!u;s2li|9<}wjr{Zf&o8mqKR`Cn4*&rGF#yj01QaSLwCD}R z0w(ww8v*|PzTN}jB`Pj8{QK|!{{8;|gOCLd|L9jy6{oELG6Dcq@B)aDq496GGsCmb z5T7wXTnzN$?|=Wl{r{i6vr6{G)xV#={AXc)t!L+QBoiQjSb+Zc`=1dU2n>I~p8E|B z6OfY_{`1$ji1Pn`9_T5yZrhJfj0}g~00a;V(9A!7nZZWFG{8az7^c++|9dI@cmDl* z!Nvb)UorrL86bdIfbsI1fk}{;;V;BV|AE?oY(}v2K-{x07*6Kx`SfB<4-V2A|A=r2_C101z~ iU~vp#0R6xN5MThlzdwv9U#bcK0000}CO1*!he@c;k+ zfB*mg{rg{#hxPwIh8G{d0|o#7{Raep|AEAFCm#U_AQp((@4x;AD*Xo({rB(3@4q1y z(m>63@(hzyJPYWMEi%>@iRTXyxzU zAo>qT2S^W413&<={Q1WKlmMyz`(Hzv@8AD_R~~+N^7b200Z@m&0zc4{Q@7rNwftxJ z^$Q??fEu9g1Db8CAq;fMkDq@pJa`8*&sI~^TtyHla^%`8uswf)HUI<=3()%@Pl0^! zf8Ui?K|l%XeRX{Qd(n@juAHz(D*15I`UefB!>$cK-hRUqIf!|Kj}Y zKt+#Ue>r^ZHOMRf{y`i940V72V*2%m0pg)Q5O4ka4>U8*PAAEH2(%ZZ;ol#C0AiF(UW*)& q3=s4Oj6m#vP&UxAe?ZIt5MTgFMVEBke8_SD0000BE0lK=nzFYgc)d0A2*B+AFf z2joHok-@WP&j1351!6Wt`q9fjf1W;g`1ALFY=DuG5oiNI0I|ST{|2JJ|Ni~?`|A$_ zRt*pr0t5gt0M7pe4IJopi4@}M{rvp?{Qds``}+I+|3-D|`uqR;{Qmm<|NHy?`uqO- z{Qn;q1i_Qs0*LV@1A}N|@t-FT{{IC^{`vn0sPGp^)o&2vABgb_!eEtCyu9%!Kmf6* zGhfda5_|CT&#%8A#S0%rhKer*8VNG{57cZ3sU*g7is3Rq0I|G(Bf-nd3vr@r@vHy8 ze*OIQ@9-oMOb-A(eJ@7=Ab?mP;SCW2x*O<#U%#>Y7zqCS`2!F@APw*!ml9!S{vjhP z$_zA&0R;fLP(1(v#Q5^%OL#2G%0Af7VC%@R_vTF*lgG%);U`26kn-@hOg zU%!6+4+cOs(0HIde9xZz`}Onxub&LUB0x(30+2WcIRJn#2ut|?gWYu1Cf+!-K%B8# zdf?1WA}#uZ8oj7u>$I1i0Al&`=O0k%-@icgAIJnM0xA6maSq6BK-ECw|NZ*S`0Lj% z1_pot6puj;05Ax`F!=umqj7^frO?t|3^&I1kxUq9yECc+jQpY84SWH_0#pxl$?v~F z@*hy-KN0|X07U)z`4{NpU%#2aHUI<=%a31wK(7Du52Oc(|3O^?R1IN+RRjI-n*kVB z3=9AP#PZ|EACPLGJ%9cJNh|>9B%spYzZw7h1%?tp0I_@ndg9MNE>313@6R75NcceF zkr51-#U+7;F#`Sf7i0rK0I_`g_NQ&Zk)EZ(2O=d>QH$KN3zEi7S9u{+2K>GX4ds`2QcM z=+A$K-~a!^(JwH9Fn%*K{{Cdb01!YdV9)*qi~a#?`wdg{8%Z^Y!NB>w;@|&31~6!UgVU(k2*|8J(R-+sudaynhucHbwAMTnor{mwqO^w7JHzaBsT z{O^B8RYf5+LvDs&KmRKVd78=o{`1#HTiEo_OolaGleS)G+IQ#sUI`b*pv<`1zCJ=H0jd{{2S>p`ri%{LsXJ%FbMS z$#S`6f|?OG!^Jxczkf6Q`UNF{l0Sd`ad7zm>({^EzyAS6{{CgrkluOb3l1A>ZU2~A zK+FZ=zkmP!`TOVhpFbzBzFaPmD2$N3;+$pK?>zdet`f0002ovPDHLkV1gy;I?Vt8 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/gd.png b/base/resources.pk3dir/gfx/flags16/gd.png new file mode 100755 index 0000000000000000000000000000000000000000..9ab57f5489bb9ebb6450cb27f4efe0cfb466144e GIT binary patch literal 637 zcmV-@0)qXCP)@|2i2MUNJEAGBA`g{QJZ3ub1IpEW7h{~Z4K zJ3#Qa=Q1XS-;5h0el2+U>(Te$zyAID&HDTIKad810Ad2W{jW5`@9y)AKr^5J{4Kqa z;cw*UKQW)B)-pW&@%z{RUqB7N{{H&&_Ycr?fB*vd;rG8kGw%JlqX`uK!_D~nn&&T_ z*-Q+-7;nUX=6mt$`7e;3-;BTi{QC{m01!YRC;j>JdmqEEKMa4Icz%Tm{+4F_^}h({ z_1{sye%WyRp84|E^4Gur0Kxx1e;6150*D2Oe>41%=Kmef^V^IA7&yOx!2%AYU;o*D z%dq`!;`!w)_PhDb-(PS30!;@9Adn3rpZ_$9NHVegX88Y?;V;N+#{WPzFy?-P;*ar< zJ?CFrnZE^h{{CWM00h;Fvzl@K2fHp9I6dqaaxb00=Mu XLcuQ~?TP?t00000NkvXXu0mjf`7udf literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/ge.png b/base/resources.pk3dir/gfx/flags16/ge.png new file mode 100755 index 0000000000000000000000000000000000000000..728d97078df1d07241ae605dff2f2cac463be72e GIT binary patch literal 594 zcmV-Y0^8x|9^h-OG^F+g7@$L?BC01YQ`Wbb?43;K=s|G$6#bNnb!1Cx>Qe>QfY2m>?Izi&U8 z1o&Rm*8l_%%a6%3nS?}u4*37)&;Q?l7=Q-<`}?1Z>;KQLY|KmGQ@ZWEch0Jnt zUmm{%2p|@g=ujpTGX@n^21dqzKYxO4`1a@2NuYivJ4XgKw*UYBFf%g!{qd7YP>5~& zE`R_4F#yj00OjT7{QUg;`}^~|xBB|}`T6Q!vcs262Lz;t$n|1+qbnVARhhy8{z5C(*C%JTg?tEV3%;s64O@&5h$(1-*>2%Ak`A87BFlP7^( gh&l)WvH=1N0MfQja}g1cO8@`>07*qoM6N<$g4hNuZ2$lO literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/gf.png b/base/resources.pk3dir/gfx/flags16/gf.png new file mode 100755 index 0000000000000000000000000000000000000000..8332c4ec23c853944c29b02d7b32a88033f48a71 GIT binary patch literal 545 zcmV++0^a?JP)lgG%);U`26kn-@hOg zU%!6+4+cOs(0HIde9xZz`}Onxub&LUB0x(30+2WcIRJn#2ut|?gWYu1Cf+!-K%B8# zdf?1WA}#uZ8oj7u>$I1i0Al&`=O0k%-@icgAIJnM0xA6maSq6BK-ECw|NZ*S`0Lj% z1_pot6puj;05Ax`F!=umqj7^frO?t|3^&I1kxUq9yECc+jQpY84SWH_0#pxl$?v~F z@*hy-KN0|X07U)z`4{NpU%#2aHUI<=%a31wK(7Du52Oc(|3O^?R1IN+RRjI-n*kVB z3=9AP#PZ|EACPLGJ%9cJNh|>9B%spYzZw7h1%?tp0I_@ndg9MNE>313@6R75NcceF zkr51-#U+7;F#`Sf7i0rK0I_`g_NQ&ZRCwBA z{Lg>@|4`Xj5kLT%`al?B=W5I`(ov;U*021*0XgD3^5{teN< z@cTDV13&-@;@|`T5QYI@3O)ok?1DO<2trehc#kXh!0Z4iC6of!=I9L4Jz5Qk(jP`l zJOKo8(qFLXAF#IH8`u5XwDI@PAHNy@|4L4RsD^0x1N0+605O4m05bkR14QCiMDQ;; z>0h$aKjWi;+@CNFzZm}i25JBZAQt8_hOB_!_dovn^Y72^zrTL{{r&6TuiuWpfB*e$ zwD}j1{Ph<^0%eu?|D0`P00`k|9}4iHT+`$2p~p=WCoxfpgkZGj{YEt g{DC2GLI4Ob02tU}a;hkw5&!@I07*qoM6N<$g4!w08~^|S literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/gi.png b/base/resources.pk3dir/gfx/flags16/gi.png new file mode 100755 index 0000000000000000000000000000000000000000..e76797f62fedcbfca8c83c51951680d6a6e9081f GIT binary patch literal 463 zcmV;=0WkiFP)VoB37QQ+R{;bN6GSUi z+kb{HA3p-oUOth}-@kwP{0U71P%%INK{Y@H82)oDp3V0Dt?T`39Pi$;RTl%zL?{P4 z2_S%&kW~Z0x6qjPzkeV9`s>}VU!Q7P|1&Wm)PrpR2q2b!5Hle5FfeebsWZ)5spT9vc*+3O2}Iw&|Nr{sqx*C2&8&?7c>c4n{QvVC zD9-TjFQbI?+i42`0*K|`>)%Y*uQL4o{r~rGhChE9{`~$Pz`@Ka$@uLpb; literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/gl.png b/base/resources.pk3dir/gfx/flags16/gl.png new file mode 100755 index 0000000000000000000000000000000000000000..ef12a73bf9628ff5a67b81bd980d9c5d2b2c0f05 GIT binary patch literal 470 zcmV;{0V)28P)J{teTOL@z0+>00G1VRSiT77W_YWkm2*^|KGm- zfAHXcOY8ruSJ7+$Itd_vn4oTd_U!+mLkz$F{Qvdq|L@-*^6S_C%a&nk00990)`(*=-xesBS%qG0|gf?f~#iu^9N|j9|i`10Ac}ZUz>% literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/gm.png b/base/resources.pk3dir/gfx/flags16/gm.png new file mode 100755 index 0000000000000000000000000000000000000000..0720b667aff506d7892c5c301af04e6bbf932751 GIT binary patch literal 493 zcmVwRhhvIeu00_fCKU~B)yH$s9sXS^B!W{?M(W&}hPbMwO z;*cg65E@7haJ!!XVgYOW|Le(9kkY?@fpY);{sqc`6amR!K*q2CzkUI^Y_hUI(*XjA zMdSH%VNp?r|Ns620Z1T|}fB<6Q zlw#oF`Oo_sVk+2%KTsoq3?TP6gz@)3Ki_`_=6?VI#CZSdeQ9y&f57m8xf%uh13`xW zAjrhTbmsgSfB<4-$Y)3kNW1sx-tWJ^f#}!YUqA$5fJva>FJQR-`S({vK;>fVMSuWe z0mcW=Ig;FxKxv@ppTFP`1*!N0BL9M&0|dYz`1hCL7Xv^5F*2kxF#KQuvOqEU3km&! jiTr^fV1zR<00bBS-TrJ5MX@2w00000NkvXXu0mjfGz`_@ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/gn.png b/base/resources.pk3dir/gfx/flags16/gn.png new file mode 100755 index 0000000000000000000000000000000000000000..ea660b01faefde01ad2527a6abcf7d1a5c1b0526 GIT binary patch literal 480 zcmV<60U!Q}P)@|A6>41A`El{SSoRd}EL3@|NdrR`1}9=ZwUJP z@AvHwzkdDu1yn7|BMY<#Ab?oFX8(t({tZ$6>;L~hU=2XVuU~(E|N0Bk07O6y00G1T zbT=bV^`Afg|NLS2{ReI~M8m&-NE-fuGynt;*hzmtW+Q3%1=j#1fvO=I{`~y|)Bq4b zU?=?r84r{KY4``%041R|`~%zYhXEjfz)k`h|LYgXRlk0r+3@c_)IERx{rUUv4^RU@ z0D&|xgN*;p0Mzyy>QQ8EKn=iP{qyfH5CNS85I`UeOuzpyNJ@hA{P_#yFfjaPWc&?| zr{By>f0X$D{QV0G@4r9|{}=!Qi18~pg5ikaD#Jf9Xfy-Svu_Nh0nj)GNi#731Q-A_ W8E1tdJ(&;y0000P)fLk0D%}*I7ff3uKv?i+N*~ULWZ>4 zW5%k%a3T{@*`z6pma6eF$JtK+F@C*&o=d^t|Ns9GOCXH@*Z?CVuP#7nB5Y|1kmu|NQ^=?>FP0zrYX%2q2aZH;)P`n*#-K1r9WbfYOYN z??RUX1P~*`M}`*mir*mb{sxCVG>rbhqT(MY2L1y54rHu+wi6(L7#SX-$0bVa{(;3h egu%oB5MTiLH(5{VMZMqv0000u-`~Ig{`~p> z=MRwl_xtx>F!}G#@4vq{&D;bKKrBFA+{}CzK0Nsg1pog2{{I_D14*DX1pWH^3y6RW zSzcL&Zwvqd#Pa7K10w^wlkmIISh(4kI3GTJhN2$mzJLD! z0*D0|DC|s(0(}1j8UFtJ4HA_S5@P=M@9)2VV#30}-~k05FvNkXnV5ck`2-L^EDTKl zn1259n3DG7^QXUm{{H**3#f!E|`n6Mz6>fhdBj29g(UfB*aM-=Dw#|NaG$fByXc1LXhxFC@THKjjKQ05P&# zA9gbr+SsEBRPB^?1!&T?30hEBFhHFGv5AR^>DH}B00G4E=NHV45I6k$@0N4rAH*g9 z{zDN+_&*OP%Y{RC0Ro8e#fvv0A_7PTA~XKMG0?q08}8kE2oOLl>koag&}IJi^WT4% zN&g{c!yE%t3}J9_Fdy0V1t5S}4xV|TB*XjR%dfvcU;YDm6wdeu;Q~GU4JP)J`S$qz^!f=A3G?{>83*rF;63vB|NHv-`~3j>`uzF%_#GV;x3_Tu z05Jg0{{&$2KZ#9J4f5RdzRdzC6Ae5p=(o+T{uB7y^ZNSwN=h$cVmJ#62-nx+ob%l!TKAE1V~I16T$|E1+i#l`u&y!03t z7ytqQF#yj01Tv_Ick58z;rzG}_y7F-%)*RRAv1X@1^f8;`}+eA4+yBm#PKA>w6y_L zQ&a!|00ICp0M7peY0>I$KneW(?7rp&{QCm?`vUdU)NRiG`uYI-`}gbY@;Dai8vP{| z4h7uY=>Px#0*Hx$0pxvffc*LW3+PFp{}_J#0ty11^n2!vLjod>mX_Jy|Cz2{eHy3% zAb?mH7=HZ$2N_TWSP@V&gaITO7A`uvc=2f<_uIFxDk_pd4FCZI)bI_+mz3lOl7E0f z{^u`PGlT&Y`3GeD{rm6lUtS;y)Bq4bz=+dkVE6#Ehk@Y-82x6z3jhKP0OI&0DF;s+ Q-T(jq07*qoM6N<$f)`^cRsaA1 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/gt.png b/base/resources.pk3dir/gfx/flags16/gt.png new file mode 100755 index 0000000000000000000000000000000000000000..c43a70d36424b66f1627216ad988cd23a4be9285 GIT binary patch literal 493 zcmV|9}7f|M~m>&%ghRD!%{(5DNnfNcHoNKp}=7 ze;EG#|IZ9j4hBF)cVB@t{Qmo2T96TF4?qC109^ty;2+Qi2B0xObN{1)Uw^{8{`KJ4gZ0H zP(J{D2s9NSfWR7{27t^!x8NVhN&g{E`Ueb#e*ggla?+pwj3Cv27=VUhwE^V&zaVoN z82$hR5DUYve}Dck14V%vK+Z)23?LgAK*7ZT@-zbjKmf4-BkT7+CNVw+pd~+kF)%WM zL>VCz0|PT7gS-eZm>Gd?16jcE4PH%g~!@=<9&!2x_@aEGW jS9>vVD)6R*AQp(xFW-Wt{{mJ2|NHk};Jc-)O#kPzME?5A`1{ZQ-#|To{!0im{$XGM z2p}eq*?*y`{{RjC%V7Pj<(}hvo^Z>=hrJ-xK=d0#0&M^~2_S%&fR6tAp8=>2$p8C? z0q7F5H=q9h`}OesIT^OczkdG%sRkpU6i@>|0I@Lq1-k@j0La}yZU2}V|JX_T{{Q!% z>EEtDfBydd!vuBJUq+w?fB<6o2X+#W53~WS;s2M<|9d72Yseq)`11cZJHs!aS-+wF z1}X*!ASNLG{ST%Ze}QTk7ytqY@{}>p)on&BOV)*xm;om>72$%sP!HhqD7ytr@1teTu4J7{m`^Wh2AGglm{~UiA z82u;s5_9PZ|FH1)~3de={)r1*?FgUtsi`kx>?C4?qC1 zfX)8@|LZe*d2K>lZN0{{I4*^b@QIr~;(tA5`a`e}Ddhy$ldQAPvkwr9kh3`~WiS7Zcc2 zh-#qDKOj^7{QC<;3||-k0tlpm>GvN7NlB2NKYyjTe{-?^h8PLd@aHekus?tQg2Ee! zfN=^CK#X6(5e!Gd)(i|h;JEn(j5jcXFhHq*fkB7?Aiw}&uW^ngBcx#f0000J&k9ol;AaCAG*Vvs6lsG2f+AJUecp&K4&zS7@MzJZZ+RCHJO2~-cn~)8*ZB# z%#~(Seaqctb3On>xdArM!+zLfe2=iS%3k1HK82I)yo62#|&;D2*%o~N(LQ$HrxFU=@<#wgQDty7s|5?>qxBTrc>UoBZ!}1le z#)a`Pq~$aEPO=D0fO80I7h5SSMqU=q48*j9Qb*%7#+Pi|ervSf?0bSFwKsAPn1FO| zKH_&kh#AJmvOUSnl~!1AmcaNJM5awz`0DF46>zWZuCh$z(7uBp0to4w2iu-uj zV9oc#M;CkJ!OT_8;~(;r&Cw`0K3r=(%@VWyiIA#;S}+n)^}q>|)QZ|IaYyyY!;frq z6mATysX~aM!z!n$rJ$=27fpoIr3iB{q|Gr32uDRa3PcNj==OQGHve|07^1DbtUgzuEQ=j%rDF literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/hk.png b/base/resources.pk3dir/gfx/flags16/hk.png new file mode 100755 index 0000000000000000000000000000000000000000..d5c380ca9d84d30674f05b95c2f645b500626c07 GIT binary patch literal 527 zcmV+q0`UEbP)00;JD`K-EmLvOuK( z0R&e6?>|)a-@i;iz|8zVIqAQ;I)|_@BNM~FU%wy-s0ZjAfB<3vx(uZH&mV?Ae;64V zIcsYEzkmP#{)7J;N}0Ju0muUq%~ z^Jl0Zz)k`PASO^y0(FCg{s2v4J zf4+RlSW)rg;lp2_Kl2?q^5yYkpazCNzyJOD%k=jzP%%INf#Tuc?>~%^l1w0DfWH6z z1E^V4lvz;l%d1x`a&jQQ{ROE8h7C|LKmaj5WMKG(8n4KVKd5of#=rm&U;y%qJ?5>3 RVzdAN002ovPDHLkV1mTk^F06n literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/hm.png b/base/resources.pk3dir/gfx/flags16/hm.png new file mode 100755 index 0000000000000000000000000000000000000000..a01389a745d51e16b01a9dc0a707572564a17625 GIT binary patch literal 673 zcmV;S0$%-zP)>fJ3En$GhGS>sbE%%m3$AD)q?8M9y>88-}kR7#RKlk!P~Y_PLuF7~U~3`~nC7 zF#yj00ZUDdpLsm{7ajP|&HwoK0Usg|6%f4L_{`Mi{rvv-`ukf=Ed&Gs-sA7L!Q7*a zj{*QO0M7pb%?Sw^g@yy{>ihEY{`vU@3=8@G0rvO$i3mOL`~mv-`W+b$Mmr&io5dg< z5v!7q0*L95jt`TzK8Kd(Utv)OSp_aLv){6ccV+Z`{Q2+asKUU&aO3`Kpz6wW8wp`< z28M3{0mSqnB#A*-c*8%1=RD#sSOwMznKA3=e&iEzwo{cA=PgXK`2OQ}gqId83!|%* zA_Kz@fB*n70M7pdECCwp4H&@R`1|(w-}M5x*74i)0}%fAt;XafA{48))#>Z>?CD#}*e}Ret0tl$#*RMZ7}Jl7Z|M45`5*URzH9L z{rmSnPy;{!u>dsyO%meg+00000NkvXX Hu0mjfN{&}S literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/hn.png b/base/resources.pk3dir/gfx/flags16/hn.png new file mode 100755 index 0000000000000000000000000000000000000000..96f838859fd2aed975f5f4134050fdbc0486ce1e GIT binary patch literal 537 zcmV+!0_OdRP)yNpn^YtfB*U? zE6K^g@B<)#SlTBTcsfda`|@_0R#{e$UZ3l|Ic6l=B#}T zWCl5lg}RFY8S^$g{qgfJOdc2ve*glAv3c@IFK6|y-~NDH^$#cn3{a5k!L9^_5>O@B z$^W^zSlTD;0tg^R28Q0WdbfK|zW)9V43odV{`~*->+kR1AO=tbO#T4}-G3E1?u#4x z0Ro5x7#++k42m+GppXWk{}2W^;6Y*k7i(1vOT1`b$6{=&w9#5#oJ b00=Mu*}Zhb7k&Za00000NkvXXu0mjfKokPk literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/hr.png b/base/resources.pk3dir/gfx/flags16/hr.png new file mode 100755 index 0000000000000000000000000000000000000000..696b515460ddb670acb7e9de4438aaf21fc5fb77 GIT binary patch literal 524 zcmV+n0`vWeP)@|4`Xj5kLU3fF!G{fyDoR{}_Q36Vv~H|Ns5{^Z)NZrr*Dqe*gae=g)r_`DNuw zfB*t(VEF(4$y0{Ee}M=nS{mB(NB;kxJOBSE{F_{n`2Y8>|G$0##TjK~fi?gH5EIz! z|8Uj6|NiY-l-<0|OxA@1MWlzkmOI;leLR z$De1;{4g{7^y$;LZ{NOt{rct07a;lk`E!5(f@%OM1_PkhC8`eE9egqWbga z&p;hdpFRZ$Adm)#>fe8W4*Ct02B|hR1*-n0rS<;(dx&bFRY1n$$BzL5h>;=uaC^Mc z(+@v?|NZ~x@4w%F|9yUZW7+yTpo@LH>e(bUfFghX{rmIxzpNnpimU?w0mQ=a>kp9s z8>AGffmuv7DrFgv!3yU7{`2q8f1ngFoPlxn4AoS-S!;e2821p2q{((sbfB+=MK@k8U5Cg$|VB~~? z2XKWZk_lAZtGhi{|56nPieMKY$Bq=4KgZ0muK;2JYWn}5;nka8K-GUCa!{rJenZIL z|9<}gF~mh#ftCOS5DU<%|Ns8~1)2?0{RgZLWF&|Ls)lL+iU2hL1Q5&LKMX(>AUTM^ zNU9+S#0FXN@8@rz^Zx+^5DWL07wmsTIe-5EX@IBzTJ`52%kO`z5F362$-h7b*KaNc zh6exv#P}EJiR%3Sk01R1^NZmZ(C**=fB*Xb3rzn04HN{CU^bJS()(Sf00M~R4FdxY z(0f3MKYtkh0!g5OAQFsz{e$TF`x|H}%fCO*7#IKo2o$W~FaxWA8VofRr202h8w1#j zz=!|{Ah3qte;CCj89_$={rBfLBSbS$5J>(7`GW}-*g)q41Q6q6a2)=FMdm+9l%onl dL?8elzyJ+{hsuy4pm6{I002ovPDHLkV1hP90PyYjz{{0J*12TXlP$`i71!VmC|LYf!%PK1iv=Z0I@Lq zVgLrRB#$I8Q2qeT`3KSlX8!?(3s3+U9e@9T1Mx3N13&;VGFUSJ^?=Y13Wr{r~&-|6d^ahvDC! z|G)qK`}^nrA0Ybu|2K$nd)6X=0AgWa1{?O`IRi-PU$8V7{r&w9sOb0ae<0Pr|Nr{M zEF}%J0U&@_82&N|Y=e#y>zg27mx!0Xgp5*S}vr z{r~fq0csvl>92pk!P<5VDfB!NI2#TFQ3lKnzfB%Al=06ZHfFW+c#KiRe{d<4_V)^&)A0s0pNIe5S)eu>r zF8~6F38(?TQZ#J<0R*xEXct5e0}KG|WIzExE=U%r7$AT^8h-rv@ecwRzz_$3Xaxu` Y0RLik?wUgPu>b%707*qoM6N<$f;0ZTz5oCK literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/ie.png b/base/resources.pk3dir/gfx/flags16/ie.png new file mode 100755 index 0000000000000000000000000000000000000000..26baa31e182ddd14106e67de1ac092a7da8e4899 GIT binary patch literal 481 zcmV<70UrK|P)1Ab?mHSU}=WzCQi??=KL1`SXRBmG?g! zeExSVgb4YXfjasA0Ybs`#&c5^XvcLUqDM3{{9AP00d^^H2e48-+%sM)d02u=%hct8G!N( z3;+QH((o5-_OE}xfO;@2_y=+i*h!3FCjkTyNW*WSt$#tPfB*dj3@CIxKqoQ$2DuvO z1O^6x00KJ+r1UogVe!Ksu!etsL5P6?Ab?navG)7lA4zUWkT?GPWdcP410y3N0|YR! zFo-FE!v&-P=p=vuVq_>~VE6=zV^DnmVAx)=U5ZNz6vaS)0m(NHWW2-wfs+9Q00bBS XO2cxg3=*#z00000NkvXXu0mjf|9Z^l literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/il.png b/base/resources.pk3dir/gfx/flags16/il.png new file mode 100755 index 0000000000000000000000000000000000000000..2ca772d0b79b255872cde2fb29060bbbbad950f2 GIT binary patch literal 431 zcmV;g0Z{&lP)WlqUuh`uiUU82D1+EBLb>EWz|Nj3k zj6%@>aVJ0ku|Ql5RsEk~{?`9D9{=ZO{V&1vKX2lHHJSgJ0SFC1p8y096I?Y|?05b{XcgblKTHZ zfByjpAQrd=h&?HOAa>`R|6Hv9XB30N3RxDY7$AV4en1PH(j<7uAT&Tc4G=&q@-F{c z8i9e$01Rv(35=ybe;NM%WdxES!M~uG0dj%y@b5pvikg1_0mOLw_HE>d#AF}?ph|!M Z0{|%qc@l5wel7q2002ovPDHLkV1m6PxaI%= literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/in.png b/base/resources.pk3dir/gfx/flags16/in.png new file mode 100755 index 0000000000000000000000000000000000000000..e4d7e81a98d705da8d7054e77e7d311805659678 GIT binary patch literal 503 zcmVl^KlW*80IEmzVa(K3*_6 zG7fg0I9Zj&0woGah`r_&Kwu3FK=xChQigwjfh>?7kc!_h@)sEWW@MKI+5iwhEdRtz z89B8WSj7JS|MwrL=l|b3uZ7Osk^B4auaUxSRgtG4v;Y11_x}$gi|9Y8?EnG9`1|i) zCPv2p|ADsrhuF4k`@Nr^zUpfTpS$xp!A}Wj4A3Yb2~_s}<0pUsVqyY2p8>1`g1&zJ zsVvR4Yya)fUw{4wtNss>0tLxGfB<5GmnRH!zxweH8<(Mq0N7e&^ba6_ z7#WHgIs!VLeti1p-=9B!fB*jb=l8$ge}LrQ-#`%%`S%Y9{re-sFSERHIY0ohF#KVF z2*K4Ml>Ykz*ZJq)UtlmW{9*tIAQm77@e!0?Mfa}mS!7%=x2KmY(S z0M7pbTSu9imq`K?75n7n_u%3MB_szB3#hl|A07@E6$<6-<>30S5egmg@cSkZL+Ix9 z0st`p&i@3O7{&wE8wU3C1oia^`T7CwI=ckcau@Q71iA1L?!*;{7^Nm*&$?GLJd|NjPb3=0E0KfCb4 z#nAu(05Jg0{{-+tQ26`)!^rI-{P_e371QGlF%9qW_x;Sb;QRdk{r*xJJ*zy?_rWgu z&$=$1lYjzR(%pFe+p|Ni$IOoG{eTR0XemVUia$~;LXXZeDO z0096o0M7peXKyl1N+90g@dyY5ARP|N&gc{s2^<#+#>?j*9u48*^A9U5-*(6(kqBPq zC^|QM0*Gbi#3NFYyicBf1{wyk;Wx-spzFb0kX0fvuWZ`CzyHEKd)}3G%ew&r05Jg0 z{{dZPvvzMc=Kqyj=IHYZ2nGGUe(f)J7ZwZK+v5TV s=!a5B6v9X#`iH^&14cjw13-WQ0BQ>oQ(TIK+W-In07*qoM6N<$f`&OQ@|4`Xj5kLT%`al?B=W5P+gNxB&nJfgpGfTOih;e`=>T z5jZ8;?_>v5xi(~iU^udv!6f5$jpNVh2O?$m1OPDr&i?@Y{r&#_{`vm=wBfh>{Qda+ z{Pz3$!R5rm=Ee2+`0e-d?)LGV)1LD5^!4@i=jZ1F2;wA$U5|F$_;B;f&rf1p(qbG! zCte(9VPa-y5lGpbZn4ZFhzcT9$vfdqmuG z@j$ZG>u9())mkwqmYHSd7eFi*FJ3%$?AX0~_kM%HFED^GKqQ#;=g)7T_f%9=fX)F3 zAdr)QMoCIaf{X{6{|BNG$o>N%f#5F;02KoS5XlH2zyJ$0KZ{``H1_}i002ovPDHLk FV1nFR>VE(L literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/ir.png b/base/resources.pk3dir/gfx/flags16/ir.png new file mode 100755 index 0000000000000000000000000000000000000000..c5fd136aee534ecb59914e336cad18d18ead2a4a GIT binary patch literal 512 zcmV+b0{{JqP)r;gUH{1e{Y(x2_S%2fSMQ?7@vH7`tSc=xS~J*|Ni>>`_JFszyAFKs{8d9NdA)L zm1AIH00;mv0M7pew_3Ln1`-ek5ajjb8VVZW^Whu|9pCfc910uY_2L}~8{YEX9t$4Z z@!Kj9D)d(L0*LYN-@lBEj6f&-|Nox>4F7-s`Ty{t|Ns8~x3>Pz!S){pfXY67`UDU_ zOc38f#US*GW&hv2{?Eqpf6;>f$N=n5fB<4bR}BO)G5?=F{eR-b|HMQT_5c3^H2?$< zb1geNgNn-kGiMln{`!CM;{TsNL8PAke-;*?JV+Z*eYOvhv$==KunT1sF?AKYlWZiGf7_{AKv_o8k9wMiBcC z1B3*kzkfmK*Ds)AfB<6r3XWMgVnF4hNdW;sfB^vU;z%SnI0)(h00004s{hykP}!$Xp8x`g@iqg4NJaUd z$B+Mm%>4cD_iu*Zzrl=O|9^qF|9<`Y547mdFIIVlOMCYL1Q5sui18rvfj0Ph3vJwt z)dnUeruXmP0|XEYv&@95W{1bGfWG{@sKWZ+FOVO6s`df7U=M&0& zKrFzJ{`2=AL>j0Rra@ocD)4hB}-f* zN`mv#O3D+9QW+dm@{>{(JaZG%Q-e|yQz{EjrrIztFq(O~IEGZ*N=lh=;=qSyMwWku z27eMOW_|f0uQeek^e_9g7KH|eq{JVG0^UaP2Jy4}|L^JL_3uCblfVD@mnS9t`~UCn z|MT(+KT|KOfz%~1cG~~^_2vEk{SFNQ?Cjg~|NsBWy<%2im{vp^YdeS=hk-Cyo6U`Hgs{l4FR(w#{P`G0;a3G2@YSmzI~fu(ZE1> L{an^LB{Ts58L6#6 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/jm.png b/base/resources.pk3dir/gfx/flags16/jm.png new file mode 100755 index 0000000000000000000000000000000000000000..7be119e03d203695325568174b72522124bb2f12 GIT binary patch literal 637 zcmV-@0)qXCP){QLU}0{l%6`#}@@_VD{9F|q;xF#yj01gpgWJ+A*m zGUYZW{T>4SpXmF{^Zon(`}_X;`}_MY3j1pm`Wy}V&B*(tydCWT00ICp0M7pd0000m zGd#J&@cQ@tG$8vu6a54J`qTCN{{H)06Z&u*`VIU0o2UAMn)~_v4c^|~0*D2u;qTwS zKYspMz5CDEtAAp>e+Mf5)@1$t_wR2Fu3uNK{_0!&`}CDxK-+|V{{|`s2p}dP{`2SW zZ!oxe=XdSY-}fK=Qse!l!T0O_!(X}WAk`4?=MOLh7ytr@32Xz9{pZ*3U(#Z~DiVIl zOa8j^;n%JAKjo!$j^Xni)Y$z6WB&k?3JlvV7}WR}00ImE Xyv9Bjb9W)}00000NkvXXu0mjf@Xt#6 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/jo.png b/base/resources.pk3dir/gfx/flags16/jo.png new file mode 100755 index 0000000000000000000000000000000000000000..11bd4972b6d5f134045d4e8ce134601ea9b5654f GIT binary patch literal 473 zcmV;~0Ve*5P)M00|Ni~>`!`VeZ#eh`f&K#;fdS|pfB*tJ>FU-06DIsWc#z@uumAs9{`&>~&q~MQB#;&cfB*tH z31sk|Jq+K!KjiuK-^&B5YLK~LCjkTy3s3{|pFco7yH$Tr@L>D>cm1y|D}MvS>F@7f ze}Db{_vg<)5c|)+zsmedM_Y~p1Q1BWd$vDo!X?isvq}Pk|KA^w>VH5L!1(y{_x~TD z9$-NK{r~sxzrPHB7ytr@v6F$JJdlAwh=Ji34E;f3{DCq4fk_4ifB*vkxQ1J~H9>i| P00000NkvXXu0mjf0T$ba literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/jp.png b/base/resources.pk3dir/gfx/flags16/jp.png new file mode 100755 index 0000000000000000000000000000000000000000..325fbad3ffd3075a4a84d8d898ad26ef7d3e0d56 GIT binary patch literal 420 zcmV;V0bBlwP)9whYk?f=!Q|Ns8||JN@lTD;`{R1ZWk|EGa3dAO8ObDh3E3Cb;oH_5X#1 z|NHy@|M?558b}5Q|Cf`4hZv9q2p|@?lb|{i68>{>{ol0lx`{mi O0000=G`P)0NEt6k^VGA)9E1hT9ocRoN>wSfaWv)?-raRm?)Slj<6Po6w} z{P+i;{`~nD6~!ec29@~tkBNo($fnHz0mS%{fq}QS{_m4#|Ns2?|K~SQUHy-* z`HU>AfB)8feAoK(-@hL}|Nr_0bQ_Dj+^xMk00K}f2RQ&hFc1JYLgN3=lsJ)M+p3uR zWC5ydAM*!ly4H1hsiEFvIU^1)HH_GYz!QMsIYt5i1c4ZMLC4DfztdU-q)WGxxg;|L zi3%uAJ2fm~N8&I2%AdL;`{4^9#;e!&D=C-&Lk8;9|NlO`c*HPy9@C${KeOWnB;`P2 zATRu9VP-jSWFD-S8kh{*zoh2aO#pT8A2W0o(w3 z|5bef!~)j#|KF3RAf-U``!@sYUq;#A42-}3UHtv;%kTfcfBpOQ3nmTE<|1vNq z0ns0zZx{dq2xP;5h!=kY&G_~A;V*`-zy9<8Vi5ZI|I4p`PkusG11$kMn1KNxfWUtE z{TpHc!>?a|&i!W8{>5bQ`~TnHf3N=fz5nHq%!z>% literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/kh.png b/base/resources.pk3dir/gfx/flags16/kh.png new file mode 100755 index 0000000000000000000000000000000000000000..30f6bb1b9b6c5bf355f67a17531fa73beafa6639 GIT binary patch literal 549 zcmV+=0^0qFP)P;@arD~1pHxO_zPr1&>t9y%wPZrAQpyS3=Ms1K-T|%K*j%o>i_=z2W0&D^Y8ax zhQELQ{rLl7|Ns5_-|C4+00M}Gf#D0s|6k8u{RAokD*W^JKSaeZAp18+HBcQ8{rdA) zTAYJ{;SE3lu^j&CtN66?*W<_k{(=kvTJiVSPc{h&pyuy)ZZrJ(`}gOM|G$0#rP$=; zY#H_d1P~L*>3>1SGXDMzbOE=49-9EaM0J&9T`emwH;=g~P!Ocy*DnU30tNVGcpOKXK;IXGH`G*aB%Pig@_cF{AXeP^XnG~{rU5QfdL?ZSim;?VE{Sy z7c(ax6CWR+s|%BWAkauYPfsQR0VXz9sPSMM00M{!7+@fO0fqklmFn#S3Nf;>{s#gU z7DjgV{|pRrOO`MKef9?wUO?vn1P~(w!@{x_lZQ{f0d@UhVEX<0FF08K{sNMJKnNIa zzrX(mdR{@6d*A9+009Ja65pra?7SkZU^!3-{)PrTC`>`Y0b%_6|LHH#J`sQb0@|>a n0T_AEh(trkF%3aX009O7j5IT?Rho+J00000NkvXXu0mjf2r}#E literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/ki.png b/base/resources.pk3dir/gfx/flags16/ki.png new file mode 100755 index 0000000000000000000000000000000000000000..2dcce4b33ffe1f40d490cb1a2e03efe22ea56155 GIT binary patch literal 656 zcmV;B0&o3^P)8t@U|NsC0_uv12fBrK4XN%za&+zB_ z{P)aXfBpaa=ii?{|9}7d|NHmt1seeZhy|?e|DWei8UFwK|L5=jKYtkh{P{kK2}m(L z`||tm?|;94|Ns5#-_IY+QnEm+00M{!r2OxHhJR4iK=k+TZ>A77)*#lue}Db^^$Tb= zko*TE|NI8J3LpSOb8Z9x2m%4nC$a{*Gqe90@enzQH`ta%tA$7d{Sv5iP&~x@8dMF~ z(;dfh&fyCHF#yj00oRR-9sTeJMNR(n^YxvS3U`G57YhIQc>VqR{rPSM@(uBDU=5F+ z{|5&5hj_*A{sI6o0M7pbe|x2IYDAmA_)R$v7XIy^!u#*~18PtP{r&xWnDPVw`hiji zey{rM^8J)$5m8%@0*JA9=57`qRaXnayHCFDJ@r1pR}vUfQ&&Fu_xE3Vu+-%{U$!58 zQy3!)avcufO?mzv0@a%gl z1HS+N7!IC&H?5`#AOHX{0M7pb00(zPR4BWp;5AJa{{8^XwcY>#`eSh{`1tyzm&^bF q{8L{tuE6I1;oe7AG|b!z0t^7P6ga05`yJ%~00001r;P)}L!W`0l>rF;|7So3KrTcC!ho;=0*Gbf0S0@;YBwbYEs=i=3_$ev|Np-X41fOr z{{tp}0~v7g%iT=?0mQ<{9!@# z-(SD~{`vL)_wRqdfBpaan?+XX#@15+0mRIp%kY{1qrJR?xs-YLhQhSVzk_f6;`sgh z57Tc3#$ODKzZsZ*F#y?2e^`Y0-&}tV5I|5HD)yDjz7nmS1pU~~aVF#A6wD&YtO00ImETIDprOD_2B P00000NkvXXu0mjfKOhx^ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/kn.png b/base/resources.pk3dir/gfx/flags16/kn.png new file mode 100755 index 0000000000000000000000000000000000000000..febd5b486f3f90056637b23caa26d838fbadd7d0 GIT binary patch literal 604 zcmV-i0;BzjP)h(K@ANy8uaQvQ^_nWcs z*Z-GL)eL_?t_B7*Kmf7KbznHW;LqhtK<$TZ9ej=*TGLweOZn#S|EVB#AOzI#2dDw) z)4xDJ00a;t5ND<*{rU5ogY7p9)8EGU->gS|Gwk>cG!LX2Y%nmu8NlfEl`8-N#0ZOI q248)K1w0H4M?n#d6+r+%fB^s&Q!OA|2rzyC0000Cs@aq@DuRlQczuzDZ5@KTj2q4CTH~*`MftCON|DS>3-+w6c z9|(gO{~7-O`v>9vKX&5_Kmaj*WME|P@B8=S6~kYUnG7sU|G#_z>G}QV|KC3#^7rq5 ze}4b}^_xjb^7)+E00G1Tlwy4KiiwGVIVgltUY_yi&tI!o|Jl8p;n#15-@icU*KbCk z6Mz3^`1ON{fdL?ZnEnBs@%JyYzyH5mxBfr4|7*t%=AfYeY;6C2{Q{!DKY#uG1wwy- z+}}Xm3;+QH(!lWNFN3HElfM4XRjZk-tp4-xFo=l!{|(XrbkBdVP9XXJ&!0aG3;+Sd z1adCWtuJ2w-n@w=AmGpT?F`?)|9k%Y-_M^QML&N+RfBB+Dh3E3pdT0*fp#rf!j_o$ zUs8faP3>oG?f*A#7{O)(oeuE;(0C>wVqgFWAQqr4|9E)*J$m%5y#o|bz~KAxm4S=v zKP&4$usU!k0b}RSKS4oYgaHH)%c-;9wWL`3={r0|OreK!5=N4TMk7RCwBA z{P_JV0}}Z6?;n_iu%H+Q{s1vR05Jij`8c?M=-GouSI=K${m;n9!7aeW#m~(x$j!^i z%zXLG*~fS9it_V|2?zl-00a;V#NgMjUvJ&I^~3uQB4T37ii-d5-u?gQ&wmw_XD?o^ zUAsm=P*7M%NJdr`Xazt3fo%By|Nn;%AAbM-ZD?YwEG7BBxA%WR!T-FR|8><0Vxn$d zUT@yKdH&)BP#Mq$fB<3y`hl076R7Rgt5;mSyo`Gea7>-}|M%}Nf0%y${3VbO@hKwm zAWK?W z+TGp#<;$01Vv<1pdP-ancZ!Qkd3bmLHK?nrgX5I}Ab=R3zkQ1wk#LIP517FKVgLC9 eRt>}e0R{ktF&Q^6#MUGL0000@P)xg`upqGzh6Lx zERQVE2><~E((v!!|G%IA{@M07EI*V_ln=0RjjdN{oM|h)7EO z{{7?6U#34`ML_iD4-=RKMg|km5|FijfgS(|AV#2u+YAh13=HqUkqe1m1{eb(!T=Kl c0)PMm0G()MDW>>^I{*Lx07*qoM6N<$g4p`a`Tzg` literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/ky.png b/base/resources.pk3dir/gfx/flags16/ky.png new file mode 100755 index 0000000000000000000000000000000000000000..15c5f8e4775b2b68e0360c1f4ff1f37e61611276 GIT binary patch literal 643 zcmV-}0(||6P)0{QUt82Kj15^L?rd`uqE`oNxjFF#yj0 z1e^fI2i-9Q(8&Vs@%;Dq2on+Z{QuwM00sm0@b~}!1OzrH#hk+X+Tt}E6bb+U_yPbi z0M7pcvI;2tA|wYPA^Z*x0300&EGqR875n@A_WS?(`uvdQq*oFTSt1&p=b-!h{Qv;{ z0st`p&i?}PGCBeX39IA)-~tZg`v#`;6$Tz2`uqI%`ThF(|NnA-^wR?L!uSAshx_~g z0000205Jg0{{tif814-hz}E2g`1#%M`@GEN)${-9=jr|Z1Nim(?*qH%B39iMC&AR2 z>ggNf+PVUWW##cF5^jI~{P}h24a1+`jKBZ?zJB$|uU|aB82|la`WF`1`0wBUe?VZ- zRnf8uXahh1u`n?Z4sYX?@pO{;x_8g;0tl$# z2T+})81L`j|Nel$KOpz_zrTNegN!(Tli}h6pb7teeq#K~3=Aa(fB<4-V9 d!wLWb3;+YKCC*ol*cJc)002ovPDHLkV1loTFLeL_ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/kz.png b/base/resources.pk3dir/gfx/flags16/kz.png new file mode 100755 index 0000000000000000000000000000000000000000..45a8c887424cff6eb0471f5a1535139b965e241e GIT binary patch literal 616 zcmV-u0+;=XP)g01!ZoKn?Fz`<^k#?O_Q1 z`=8<8e}=z6_5c2{{QvRuAM+0emcRf01JR%V|9}7gKjGLHfB<4)U|@L0AiL;yFw=jq zasNSbGXHKG{NMlfpWxpAK41Q^gEaj6FV4=$@arEy05LIu!2gi{Gync$`1$|;-~a#q z|NCw7f0xa__4fbPn*ZDO{onuJ|3JnA^#F|o2q31v4F4ql-&_7K9cVD)|KCjiesKSP ztM&iLe}uy71TZ z|DRv){|H?Bqoe!x=x?wkfBu3(0w91`fMN3Vzue;gQUCt^|MZVr;{RRU{|DCmOS=6} z@%2BU5C8a_|1a6~&;1YB8$b;J0mKBvKpP_e^#OhS_CN2(f86)~DtrE)Yx94t!v9OT z|MTDe69TJd_zQH>zdry01PrBrQvYt3|7!q-C@@&>{!_XBPnqZ6E6@K61pYml`M2uu ze+NdW22lI}1Q5_kK)3wPV4bt}e=;a?{xkdrMUmL?|7pP3c>kYY0b~&4U$AjN34j1% zWLW#P{SRLy(>r)v0s|Y${(}_LK*N79FfcIy1Q-CnX{(%t#68R664G@6GIJN-*24NrwB3rW+v!ydOp^Ef6{n_)(btIFVjHa=pdp6)} zz^!@$h^2tpKUmc4)64h&|Ni?2LVth#{QKwk-@kwU{{Q=j;qSk{fBpc`pWlD@C4}l3 zHUR_xF#yj01d}3g9TFqw{rUX<|NZ>{`TG464+L38761SLpR(uO=J){s0Q&s>`~3bJ z6bIb^kphT`;m^O{e;I!LWBmP>@yDNkj7*H>@iN-VTtHNrD96Ue^ySz8pMMxZ=pRTg zKmaiT)&Bj@@b3@E4ZnZ>72sjw}n?8s2>T{qV)lKMV{%|NQ?241(YPff@h;hz00Cp!a_N2HF7% zr}y9gR8D)C;wJ_Sx5=xYz5MWpi4mv-=yjk&KmiL7K#aZ&_9^w5@1DH=3l15e)xUl~ z-0=7B?|)4HL4sh3f5LL21siGr0*GY=!$H*K#ZR;BJ~dv8zS`wDeeIR3;>1y|KC3hK=RLTAp0Mf zWcc&@%EC-|_DIyI;S5 zZoa(f#*3@};Q;9GfBygi2&4h78pxV*WHQhn|Nk-k{`>pa-{0-~I{v`b{|EZ(4?qC1 zz%@X;G0|`0)6dV-R;K{9rJ5v|%9;KB_nVP{8R7~c2@pVx*BKb3t8)H6dH@UxP=NgY z{qNULVEFv`^^@@rIK+N~gX`}f7I~!;+fM-m5DPFa{(t+%C?E(7W+q^;{`t)a3di3} zzd^yz010JK%>4cT^&8LzfB<5=h#HaqkRlk)Wq^@D01#jR5K~0vg#SK#00000NkvXX Hu0mjf%Ubyh literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/lc.png b/base/resources.pk3dir/gfx/flags16/lc.png new file mode 100644 index 0000000000000000000000000000000000000000..a47d065541b0d998da832e1981b479097a9b36aa GIT binary patch literal 520 zcmV+j0{8uiP)#-NSZgwz{Qh@GSmETWyIzrrS!pkkqDDw`CEYY|A1Dxfxke?UP9EWUlaZ{K@! zXYTRdfWyFioqIm+xW_M=V(hYvbO?~5ZHkEt37xh?rY1@PqM%`P+i2w@_wXJJO#nzA zheNt~+w1B3H|fqGMx=x!lms6SMy;uqQ4R``NH&49%B_cditsDHI6DHXLNubec}E0~ zb8dy|txA`rTkZMN{rCM3FV`MqlfuwZrz$X1)+?ntF|UvTkD3M?FxSaem74ag}Vzy5sA+`s~GjvDl6>(E?=UGu{=w?r5#MJIwhn?GrT#s zeRSo}v&#TUmcjL&mxEF>2%EIxN+SI=O=izlM$T5JH;yv-C%^zTfK|9CLa`qJ0000< KMNUMnLSTZ|5$YcR literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/li.png b/base/resources.pk3dir/gfx/flags16/li.png new file mode 100755 index 0000000000000000000000000000000000000000..6469909c013eb9b752ca001694620a229f5792c7 GIT binary patch literal 537 zcmV+!0_OdRP)sI{|q~>>TZ2$qp!tjsj_dmuxH+6SkQv+K1^Dpafp!@&+{r#8W&u@@le*a|z zk$)I|{ss9HAb?mjKkZQc#wYOgBhb-*|NQ;?=l9<~e?U(E{r5MB3DgSYf*4|4g1Z=I z0R#}sfv@v<-|;cLeDMG8um8XQ{Qv#?|LOa4L zz5|hefaLFgf557NB#8Tm`R|`M3=9AP!~zPVKOloaN+E`UP5lQo8*B+s^WVQre?jpA z5I`*dz#16EB$cmd~05Jg0{{#R40Cvt10RRAw z`u+d`{`)-+^5ON`yb$y0|Ni^@{rvm=`~3g>{0I^G8ZGb(2;2e)q~Yi9|KETAVEFqN zi2na)xwe&yo%hS1uZ%yx{Q;WF%<}W+mp@!0-yWP|m)B$h2q2(_|NnsK|6hiGKudoE zUGn9{-`6*oEmQ72y~rUb^YQPmzn@?Idwh=T>wA{p3V#3shzY3p@87?_|NZ&@_cy~| zpmRZP`1kJ@JI^@8AFa{s9OeCZO+ts{j1?4b<=-Nd5zA z`2GL?FD{9%H@9*#{QvEce@o8hC9n7wpg7QIfB<3vS^!iHvfyK-U8V5ZH#le}4S|yXQB^Nt}W|`Q?5-JjKDn&hY;a$Df~n9-WqyG5z}b zHWMS`AAkU20!9tv|KD6JO#c`e|FbePFfi-*z4`Hxjg_16|9{rM|5*PsvHt$a@%k1I zzvO#v;hz8j#Q5o)BT__yf)$AVfxHBa6HpujodJ?%_y>%AV59*A7yy`5b5c`Z!JhyC N002ovPDHLkV1l?nIh6na literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/lr.png b/base/resources.pk3dir/gfx/flags16/lr.png new file mode 100755 index 0000000000000000000000000000000000000000..89a5bc7e70711575c1ee3b83cc2be7f0e1fb29c5 GIT binary patch literal 466 zcmV;@0WJQCP)2Y|A4{o z-@kwT`t|eY&mTX2eEM}Kp+i!_T03wQQEla((gZiC0cs^;{c3|jAkj>009Kl@aN){ zC);;k0UG-E&);Xo*&wq)roznr3pD=Ezu&)DC1p;}S_BY4jKAN$W)>8Nm;toyKW@Ot z#Ps&Y4S)b*xg;zq)7SR<*)x!NAa?^@4{|ZkY%l|8FPQu15397y$%U%{0*LYZ>zAxx z8}J(slm+_X#f@tK0mO1iR9wET{^!#tU}GSb{Q3uSG}s1+e?a74b~(9Y%Qpf95aZY9 zPuWDo(ENa58%O|%pI^NU5I`*FB&GkLM&}>Ys6}P~0YHEO0B+J}4VS0Fk^lez07*qo IM6N<$g3a05u>b%7 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/ls.png b/base/resources.pk3dir/gfx/flags16/ls.png new file mode 100755 index 0000000000000000000000000000000000000000..33fdef101f74e38e2422bb85dc8a31bbf1da326b GIT binary patch literal 628 zcmV-)0*n2LP)NT^udI6UX~&u_xA`izWBNXkIq%g^6Y%Pu{8|3yZC zlYxl^Ab?nacHcU-^!@XD|Nj5|`r(zVwkHE4BV6^xC+~{3+xxCp=yQ1PA~B|JUd6PoU1p;PCnS`uh0!`Wt}y4#)fi z@&Nb%0tn=Xmv@c{N@*}KFh0M&kIP1>YRmQG4?lbdn);9N*SEXB6{h}Te)Ie9Zy;d! z#Q+chF#yj01pfa18Ye&*C_n-K{_XVnU82h1@caA!0{i;;`V*Y{7}WX#^!xhz{Qms? z{`>&^00Ic4fsvW@|G$6Ruf6C#{P_EiKfi$f`+Dz}{FL7;Z+`vz4fMjFe?Sd?fe5Gp zAb>y`UVr&E@!c&!7K){sO`Ozkh)melY+9 z5KGUl3lpbYV0iHf6xF}JF{n*t;A3C_dhHtn&^!?O1t$N2Nj?UE00RIWZBXJNY9>Gc O0000 zKY#!H`S<7dzuzGA_xCRl`Rmu;Um!M^l;`6=xPSp5fLIuQF#P%V7sv;y25A5(1xW+7 z{Q_w~Xakza@Pz>&fLMUe`uqRSpZ|Y=>VQIE8-4+ehiC(l5cdDyKm=3_5I`(zTN!l! z|Nj0Es0O49Xx6_!5M^MM5b`fj@gGk4KbtNx00a<=83P0Vn?HYFf{Xx4|Nr&tKga?w z11|FC_y0eCSvdcCFfafF5XlYnMRN&=-B{`>{W0U03nA0WvHB!TYz`r< y{$OAL2q4DW;E4VQBmbdt8IZ(*2pDGo0R{jiB6maa(%qQ=0000! literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/lu.png b/base/resources.pk3dir/gfx/flags16/lu.png new file mode 100755 index 0000000000000000000000000000000000000000..4cabba98ae70837922beadc41453b5f848f03854 GIT binary patch literal 481 zcmV<70UrK|P)?-#?r-wgj45C|ZESQtLMVW?~Zs{a4) zALIXj41fOq2a1uNeOQW%&E= z|DQh$fB%40fEE4z10q3;-;ClCKpOx8h=su~@}N>;ErcnO|V^hXG82+5i4Q+5aFU0|N&GK!5=N X;lz1sunOP500000NkvXXu0mjf*7env literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/lv.png b/base/resources.pk3dir/gfx/flags16/lv.png new file mode 100755 index 0000000000000000000000000000000000000000..49b69981085ff54568907cd51a56a1e5d8b01ada GIT binary patch literal 465 zcmV;?0WSWDP)TuF);jrk;v#5jAUY900)zv`N|Ns31p}&9s{rUUv@1OsF{`>=? z-@pHYNg(_0@82^wZ2|}&78a1v|Gz$Y3Q`J0Kshi8lm?N%fQ(=Ne*FS+xn*U6mIDM3 z3(!4({{8=rtQsf{G!?8Agn$gN2Dab7KQS->1Q6rPlP7uPKoY|E^ZWmwzrbJwx)~sVSb)*-|Mwp*NlCCVfB*i0>4ZfB zFhYR-gakS;`Tzomv6O+~6D%TsAw}vh)M$o8KMw-~K!5=Nd?C`~#DJkl4QvBtQTT<=hAW5C&pkLRXaMS_oX@ePCublh%7`S0>4^BHJ{X z&jSWU1bzAnAdrUt4F8|~c=q?-U!ZD;3Wy>I`UNEa{sJFg8g4-`_wR00IcC z0c`wlknw+DNZ2$-$7NDlT|NlUo0ap!i1F~k2r~my1Y5)izkcK~h z{{rRU9);Krw*=%9uq;py&^Z7B1lI8X4~o-~jQ<6)85pKOHYf~%iU9%$qyZ=)&LIKv z04P8aRsoF!DgoLL3cdee4gVMb0*H~J5hWs_B!uw~i3^Ex1_pot0|0+0kn{N-xWWJc N002ovPDHLkV1lkWn<4-J literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/ma.png b/base/resources.pk3dir/gfx/flags16/ma.png new file mode 100755 index 0000000000000000000000000000000000000000..f386770280b92a96a02b13032e056c3adfebfa18 GIT binary patch literal 432 zcmV;h0Z;ykP)@|4`Xj5kLT%`al?B=W5I`(ov;U*0{`Ko0*gOW1x?dnY zU=0kve*-lD1P}`lGXhluRs8wG@Eb_}{{H{>S-s!?{`@vR^^5K2FR(pO4M5WY0*DFZ zqCZG(`2G8?)UU4`zrJw%x*-cw4MBhY08Ix7Ah47E{sH^x7s!U+ztwL3`tbkv-#@=J zum1jzWCJ7ENdN%^b`n?!@|4`Xj5kLT%`al?B=W5I`(ov;U*021*0XgD3^5{teN< z@cTDV13&<=05Ky_HBiN$KMcQtBo?#b8i1w)1P}`YD=UMn?0*)P|9^oV_=9jUlG7n1 zgOt?2g9iZui1GF7*Fr)<|ABx33~>V{CZ_AxuLA@S%fEmBAbhajaRP`eP%%INfiyrk z1T_G`pFe*90tjjYTn_{=GBPrt03a7C3lKmc4KH52_yY$2zyM+rgbiXafFO_o^aD@| aAix0StzUbk+v2SN0000M*00(~<{@!wBU}0eR!0_)M!#^$%c|o1wA4mpD0t66HlA)zv9Z3HD2a;wKuKxf3 zKLhV?#{Ykr|9@us&njQ==l`GI|Ns8^_xsQFIm-b82&94GKf}}4zyJRI4@Cd}JZ511 zyk#BtzrVk|eZKww|NG~I-~WGu5Q~)bF9rsH0Ad2#1T-6>`p@704FCVWdiqyE_S>%? zzn?t&`v3p0|G$6zgQ7n`R{;bN6VP4%{xkdmsRoGvjXbc2Q*ib#i+$e?>}LD_@7KRy zzyJOE_4n5=pu>QE00u!g^X8F}1){Re7)$pq2>GzRP>hz5WF0{Q`{ z7%1`&WXbP;Kox)fFb41M1d2p!76A1_RfAN3oCFX+Kn)0M$tdvjY9_8yH^9QVjn@nfZP*{rmI(|3?O9b~d@cVAX$tK?&3V z5I~F!3@gDg2t{v?r~d;6^$&1NgV7;ZP#i-L5C8-i0C2iwRaxXp%>V!Z07*qoM6N<$ Eg62#MXaE2J literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/me.png b/base/resources.pk3dir/gfx/flags16/me.png new file mode 100644 index 0000000000000000000000000000000000000000..ac7253558ab939481a85cc06dcc4d73503afb9f0 GIT binary patch literal 448 zcmV;x0YCnUP)l$FJ^m&#tWvBA4C(n)b76qu^ z3TjKJi*u=MzAs;^(tHqT@6cZ|8AHxz+0T%zR}I9mkc`8faCz48MN^H2?$<3((yN)j;^`52o304M1f80R+|X9}Iwu*X+N)@cjDs2c+lU z?_dAGBv9wyKfl@e{~Tjr001}1@4rADVDj%Tpgtwu-=}^u z00a=o2DtG+^6#HtKYxRyQB?o^{pa7Gzs!FaUNHa!5W-0i5^f%h1nT_t=O0kRUm#-m z!vGLKP#fTS#5u+P{rv~@0nkXGhChFS;q~V)5d8o97pUPE13&;VK7Rc89~k`k^9M+( vx2Q8b0Y@nl1JFDW`UNKcfk_?)fB*vkB(P&2-J7g<00000NkvXXu0mjfGX%sy literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/mh.png b/base/resources.pk3dir/gfx/flags16/mh.png new file mode 100755 index 0000000000000000000000000000000000000000..fb523a8c39d40401b9abcfb144a73cbb2d76b286 GIT binary patch literal 628 zcmV-)0*n2LP)qpJCu1p{#SASZ=3QjbPhlO05Jg0{{#T~{M_a8tGL(@4F<^6===Qr`uzX+`vVjI z>RSuFND|!tCprH%UjG&-`Tqfgkh}r_F#yj01OWa1_W1j+!`}P+|NQ*@_xS<*{r*D) z#ao8o+xY#_%t@QS?0~yfBW+Wj{_zyJQv%*f2f%)|)v=^uaq0&4j6{l|Ybrbh`TZ`2ITPyN!~wBya;Q+wXO z|N8qsP{n^H7N*~zApZOB??0dhfB*t%@KJoPW~Y4ZyXB%oU++J<@%!g5F#%3te)iws z==lAQ0jwGr+CT&T00a=DyL0x5XB;1||6pKv0FF^K^bd&vjBEyg00RK!=O6aq+V@KU O0000p}y_ZxVsQQo9l8qD!tQ%&&F2zEbEdU-v3mY$p-gb*;wwp?LFG<9EeNpZLj7Q z>zeacpNZ>XJG@0bcmXcALo;Ad(L@#C92p0~G#aM!FfF0T7^YIJVVFaIl|0gRpSyF_ z@0dgJ{oT}qqUk#4;-a-U9Fej5EJ`tIE9)E!qDfL@GEq>vEDI}q@P8EmenIHxu!*Cc zLK?@%1j7u0A`mPlm`kyT;5daWs;EH!+LV0IWO0Zyj4+sHxRqia#e9ki#cu?^6YQn9 zOfZ8&4uw%r9nR_}FG?tJ1sBpnAsdGMh7pA$Mlm3ABvgz9aj&GrxaT8{1^YB+UzPEM zQQ5*0;(QnblJRNh>E*%16wccXl466KPu9Lk=M%$}%9~Z3xs9na6KbZ+^U;AoQ+JVg=BO3kgY$Vuu?iP6r(sQV=EH;Iwf|hcN2Nd zPl_EfW;$kS3zh=H4ojC&X!7Bd!`~OdX{VxLp z5dC3f{KL%rhe`hT|Cm4jfB*jf2Sk3^vlaWpqpU2@27mx!VE|eEAE^2d5dHlPWd8sE>;L~hU=6?i|N8~f1J=Os z`!`SnKmdWv|I6_A575egAcQa*n+Bj_fB<3vdK75(@4vtQ{Do`yh0yRHtQw*LD9^wE z5I`Uef5B$|`u7W{2T22%M6!Vq>?D8y0%`dD|M#!IAl1MB{`!Yz!@u8fUYwuxex*z#9GlH2{4I3~mO10Ac~g+V6jVB)KI)-uUyEi4o|t-;5vX%A}^sE-TCS?;peW@7xO)zGwLT z>;Lb2Aa%cf{|B;v0lB{!Wo3aj00dxJ4sHN|VGstA{YR$4C2D_2_!cBcz(8l;%*ju; z_5-pDt^fjRVEX=(;rPk#zkV}({q}dw+K<0~Gco-B2UY|%8?FIpIzRw{{P+Lo&pY>j zzJB!i)2Bb*-v4F%#qjU=2Y>(qX<+*Ohe1*jY|LMVKOmiqU?UkIBoO`m3qe4|00G4K6*VFmu*EK13J3rK Z3;;9iRuWt9^;rM_002ovPDHLkV1h$@)rkNA literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/mn.png b/base/resources.pk3dir/gfx/flags16/mn.png new file mode 100755 index 0000000000000000000000000000000000000000..9396355db45a8ee040c790782209868acaad4b85 GIT binary patch literal 492 zcmV@{}>pU8D26lh`@M2^zAEy;6E4#hyVhJ1te8n&0xjw|I|OmAOC9q@qGTx`1kMs zKYtki{9$JJ&B6L7=Kt^CKt7QCvS|}Q0D(0y{Qoccl;O=^hIfA-|M~k7Bn3tPfBpOS z`}Y4|zknP@Sy`YB00G1VQttboLEtY##9yH3?>`J++5f+PL6rRiQNLgu1_potVgX{t z{eKx$|NOuHhk@zOpC3@OA=>```VZI207MK7009KDfg$woe}>=xgMa@Q`TZMV99$1f z=+7UZ=>P!)^22||KmS$!{Ac;a@cR$YT8L7JY6c`57{N{g2q3VN{s9Bw7X!l|paf9r z=TC&I7$7zP9Rm!dKY#u(FaQJ)NCWfVKmVWoW?%y` zm}dTA_#*kA1?Z>0QqoLZAnySq0pv->KTM2<4My5DUW>hHBSpkmCRUfavf4zkmMxWn=;={POe9 zpZ~vq|NHajABg<@_xGlmn*aic1*nOE;s2AbPk~B-;NSn>+$?|p{{I~>&N%tu*Drs5 zfBO0B*Z*HY)v`RYKsx~fhzW>+Cjb5S_s>6&>Le+qufKnBv&bF%YWVBlABO)w3uGC7 z{rLq%Ks`WL0R#{e(EPs)fB*akI^_5N|9=)g|N8#t9~WuY61}otf4Tqs`!(tD7m$X( zzkdG%X#fZyCZKPCW&?Et`7z=QS^~DI8Yx-=nhgK{7whGvYgWDg!B8&G1k~{7FHk81 zKmY(S0M7pd06qXVA~x>%?)v`v$?y7WENVL!I|c#<=Jn<;5-<%03=swpg4MkH|N9RH z59P$=0*D2u3CIB%01Ag+CC5rQSvY_G`T70NcNRvLcR${}{{9+hIZ*cRKadRo0R++j zv0Gk5I)>DQ+oULEUYSww-@{VeP#&z`*?j4i%tcfB<3v#u_k;CAlSmszIWE zes6rZ@!!9HKqG(r{Q)GE1e8GG4GeUkhF=T-0mR5q%E0gm7LmVTk@^EErhg$tKMw;y afB^u%K|axUkwLit0000IqP)p`2X)eQ1zd`|Kz0p8A$%R z`bTZnZKVTj3KfeK`2Ky*5B&e@&)?sFfZ#7s13&;VG5q=W=RZg_5SU54z5Mv&imk%` z|FW?#NF2HHZpKX|PKHOnfBpIO`|qDW|9~0*0*DFdzkh#$Hv9ux`j_+Xe->2}ZC)XM zHV0!dKPS0Ur}$Y}|Nr_6wBa96o`K;HKmdVl_zUt7(16dMgtTSeTz>rQ?Z?ko?mjsC zklD%d+V79-zd^=BZ2$-$7GT%`Z2%eY=kMmT9MVkp=Y%mFes6g9+4CZ|=Y~?>`*tz_ z9Sja7kOqJN0yzojravHW{k?SeQ|&okK5=fKkARLe6n%c?uEf?;0ubZ>f;9XA2p|@Q zU%!CHiwJW41sn7GB}e}J|9v$?qW1mmH(Bw2pdk4RbO%twKY##YWMEE2jz}>2 jgG53Y5Cqh~01#jRFwa04;J&RL00000NkvXXu0mjf4K^ZQ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/mq.png b/base/resources.pk3dir/gfx/flags16/mq.png new file mode 100755 index 0000000000000000000000000000000000000000..010143b3867f21e7791b8254e806b325c13b2895 GIT binary patch literal 655 zcmV;A0&x9_P)$g8u&g1qF5h0Q6aJN-{1Mbz`Ie0O|k$ z{sM@ZfzzR@(T$Ir&B098+eukMUeMl2+1^x^fq~&CAE%jZ{^O4ipMU-bgNM&P{`mQajg9%ivrm#DT>t+4XJGgP z5I`&pzyAFG^Do#{Ra%^vg_(hwneqG2-w+MozW@IH=Wj)-86P+6=Wo9l8G*Kb0|+3- z*{jc+=}JF+`H7W<>HmKQUT#*P1{)(8poaY?9|3*x^4(W97N$Rc|4EDS&R=&5Ab=SE z{{73y$Ox4F`Rgyx2o@H`|EK_{=f}^#%*+g|tSlctd;ka_mU(L~nd(ak@UpY9GCq0n z(2rN05Jg0{{a96b$W_S@ACL(Rxa}M z`G=gy|Nj54lTiQv|3YG^`}+MH7z}h_G^4TA+~V=RqI&{}iQ&&bpkF?J{dw&CQ*JI+ z5dlsHn4|vw{rBhJzZb8+p1k+fF;B_XE! z42<9q0s8Xa-+!garV_&3Uw`~!Vgv;%KmY+HvKbgYfiyF)F);jMVE6!x-Ip&{0DU4U p=>-f&1_my$6wo1$fFwYG0RX)13*@;vt7rfK002ovPDHLkV1lt{Hh%yB literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/mr.png b/base/resources.pk3dir/gfx/flags16/mr.png new file mode 100755 index 0000000000000000000000000000000000000000..319546b100864f32c26f29b54b87fe1aee73af21 GIT binary patch literal 569 zcmV-90>=G`P)rBb0vs`uywH-=91j zzd+y*NDt6q00G1Vbl+cwzkmM!`SbO+m+YTk|9<^u`R%^_m*bXSzgT|#{QE0P`4>nh zQ2ZZA13&;V0loO=-(MgHX#3gMzn3`u{`KzHucyC$Kl}CT<*&8wzt6n|ss8o%*Pp+C zfTjZk5DUl#p#T2<`NjV0^vyqym4EMy|26&E??3;3WoiC?{O#A4)4zWSfZPMI0U&@t z8bCe+8UPFj-d`E(e|zZv%GLeN@c(z$rC;+8f>rHtN0D&|BIS>OtI{AOC zx$tZGDUcCBkzc|7XAeyp!)#=hy@sHz%Z8Nmi!G71?uGb{rk^vkcEsO8W!D1Ad0T=%Vj%gtVfB*vk>3V2g53(}_00000NkvXX Hu0mjfpCtxQ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/ms.png b/base/resources.pk3dir/gfx/flags16/ms.png new file mode 100755 index 0000000000000000000000000000000000000000..d4cbb433d8f9fe49f06585dc46ee15593e3e621c GIT binary patch literal 614 zcmV-s0-61ZP)w!6%f1G{My^>{rmp(`~Up={s8&+{Qm#<{R63-jRF8M0M7pe zp74|h+7SfEy9M#{{`U3;5)b(M0y+2j#`QMv`vWF8IQ;$o{QUp?{QmLR&;S7V0*Gk~ zkHv3!H5OU9Kb*Y(q-ELEH9vC;U*%N({+r?VuV26a{F4-VqagC^H&EN}zd$De1Q633 zj~FHafsLPJA96}RV-#A)X~v?X^MOAye@1K9u&05Jg0{{zeC zH7h(V@9+2F_Xpti2mAc}=j!&)<^S{h0sZ;_Q7ob~2($C-{v8Cq(%>lF*}4LV2^e-j zV}AbzqQAd@=ogUu2Vs2v^{02G<;{1(|2aQ(EV23Z2N=G800M{wXv^O}|A7VrH9+)$ z7=NG)mcRcxm)QV402KN07wDuv009Kl@CPU%A;t|Pff9c}I{*Fo2PXf3L>PYm|M&kd z6T{yxzy1Ri0|XEw14AS%MzNxQNDQDd27mwq0OfZ^Ej7^!+W-In07*qoM6N<$g6Gg9 AMF0Q* literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/mt.png b/base/resources.pk3dir/gfx/flags16/mt.png new file mode 100755 index 0000000000000000000000000000000000000000..00af94871de66cd0fbf0ca8e46dc436d66e2f713 GIT binary patch literal 420 zcmV;V0bBlwP)Io>l+&W2PtRx|M&0z2M_*#`0)SN z@BhDl{r~j~sG3n$7H9)N0I@K!uxMy#e*W?mp&AJO{R1fisrv=e1J=Os`!`SnKmf7) z1AD;K%nYO&458rnZ>;h=xCZfJy-Z2&4h30>ylo1|%C8 z!A=4QAQtS#|N9SD2R9xVP=6R000Ic%Boqz*|DhQF2dLpM!{5I^H2?v`f~*=Iag5B& z3^Fndyu3hzLFn&a2m+c75I`Us-n@D94+enNf~Z%o__l08i(?1?2rvLmwOi|Xk;8TX O0000wT1SlAdCl&Y)$gVg>5qW^#Y{{Qp$|KC6V{`~n5M8AIn z$$wxH$UeVm6F>m5>|$VWV&MJy|4IE<4N06-W9 zfN4+=|Nq*iiwn$Q2C&jbT&$=TD3oCSlHOGFpRx(;BY;>KBo9alsWSh04>T2o{{H<9 zq`@}){__Va_~#GM1}QP2gACgN0*LYNU!Z^U|NnpRpWzq7|3Cl#|Nj5~7gmyqN$LIj zQvdWzhA$B4g=Z%5I`U&fgJtk z_g|1x{{H;?U6oxK=&at?J**6@V8K5Oe}Dh~1#%?NbbtT?*#Hy-y7l+}Kff9N{$pgg z_WK6Ie}+7v0!uEdpa1{-Wc>4s0pu$NunhnK1op#kuysJ&8U8Z;`FH#0jm^LQ>Tv2E z__*)izhD3U{sq|pR0FmFAb=oF`osMFS8?ijP~d>v`s?4X6Tl#928Ghke_*>=zWoA* zI8ZS_0I~c5+3<%^Qj!Z4rNibE_6+kRtZU3J46>yw zfWS`r^B2emYGC;Nhw;yEHn21ZK^Q<1%m5k+3<-b$0%`dF7h*inus>j>Kov-;VIf zD*pWek$*v<0SxiK|NjEzfQkVEh>@X`f#DO--wX`DVCWAL;}4AS4@`0~00bBSj-y@M TF2~k{00000NkvXXu0mjf^ET$> literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/mx.png b/base/resources.pk3dir/gfx/flags16/mx.png new file mode 100755 index 0000000000000000000000000000000000000000..5bc58ab3e3552b74d990d28a0f500e9eb6209dfe GIT binary patch literal 574 zcmV-E0>S->P)LFc1LT4cKmY-iGBrkbGB7ay`}g

Nzrc?B z!}RAj&|v@p#KiFL&)@$*g@6D2{reke@BjagZ=QH_|HA5tt#{7v1Ul>guV4Ru|Ni&u z_rKqNfHnXG5DUYvUm)ZE{sF26>H%tC6A=5t#K$G4Eg-G_A87rbKVS#^0WyF#00a;d z1Ca3#WHt~1jRI=eclPL04k1AU{avRH{sTG*Y{UOQAO!R;KmY+XFaVtnvEdic(+vNe zOr8IIc?-17*~$Z`|L?Eg|G`fB4^+g!01!YxCouq>54Pd=FQ6a({TC7tjr5F#2GXxz z|3N{=01TJ^fBykB00a<7!|#88#Ce2)8ovGh$;ikEv=>5x7)(s8a literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/my.png b/base/resources.pk3dir/gfx/flags16/my.png new file mode 100755 index 0000000000000000000000000000000000000000..9034cbab2c02704b65fba6ecc4a7a1c1d053b6c5 GIT binary patch literal 571 zcmV-B0>u4^P)Z-xKO+5@Bcl`=5c~|G$6#Vc^TNX8-{JF#yj01a@w+002>mTdm0Dxpa1{C#)An)W@eTA0)PNwiNI_f1h_u_DTrb&+z}xv;{Wj zFGj0Cgf$G002ov JPDHLkV1gu%1+M@A literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/mz.png b/base/resources.pk3dir/gfx/flags16/mz.png new file mode 100755 index 0000000000000000000000000000000000000000..76405e063d43f2f3b5b9cae4f76d9f1c73cea25b GIT binary patch literal 584 zcmV-O0=NB%P)d!0?ZO;SY>NM!#Sr3j;s^4&s;y01$=&U~zyG1R{bN8&$-J2AZUB z{O~2s*67}BSLujJh!l{(TM_&V!SLx<0I@JIFetqFAHVYHe9OP56#xDPD){#oDEIpx z82$bI>))?me}4fPvfQ#j8vp_bq~ZU+|9p&pvv&RstuJJil>ZL~|9}umff)b({bONa zxh{1bAb?oDF)-ZV`m5;k=ljw>l6BpeezVN}{rlPPKR~N~|N8X{NCKH4>bI<%?516t z00M{!=o3jd#=5m)yzyNB8Nca#eH--U&Fe3(f#?+keR}os(@P+F`}Hl*IRF8~0t}ng zTmN>%etWlrgX7)b6MtD}{$cp_8-#v?7>pqD50GU3{f7;x0U&@Fe=;yIS7rUbaG!zu z&%cJ+j{>}Z{{3SByBg&1|Nj_3~Dr2e;Gh>zZrofD5`!lF#Z7{ z2B7#~hM#}`y~Cfd!0!j9&~4{}>qlfDw=_GI6Spo7yiaSL1(R34j0qF#yj00RRApetkm@ z3-<^I`04Bn_xS?+{Qmv@{`~y?GBy}bOB@O2-v*J4|MK+z`}_2=vH}QbDjOT??*y+^ z9PHma=D0k1DE9l$Z%$6;=mbqObq>D1hX4By|NHgp|L;GHwRPtz;{gH)sDXiz;U6Qz zZ)V2dKoY20MNK$ASA+NcQ;z)f|Igq2|MmO7w9@DL!aL%O?v>U60R+_W>(dw3rWqbw zY+vs`7YYhj_p}$}TRP+a`c40T|N0L!J1pWwjPJac>kgmX!|;RwAb@}x{`~&)@5xJE z5fO>bZXLnj?>WlS|KEEGbn$;~p|4%Vx0QJ+&gI^Ic|%b^5f~5v0R*z)@87>RPSSB9 z(mdPNGA>^D|K~4|Gn`ysXGCuKcCvq8=a*k!egj?m?>8{m00Ic8fvd1cUx@iTXM5HE z^H)FyGjo2eEq-FG+;YA1)Puvn7=8hj{`vO@7;-=x00M~R?)3!82NxK-n*V?K1yZeJ z{HiGaByR2;1J+usHUNMy48Q{FH!M8N)Pwp9Y)wTFo81A^+}-HTA|tp~ zO4-IyLWKVGUAVv#KrFzpU^vb8&*4vW%&*_Sfp-5+Oa#jR{(FIy5oqwQKVTa`BqPut z3=9AP#KLU;d%N^MnR|>Uj{MoN{TEQv&!4|iQhqnS=35v13ux)DKYxDz{qyJVA7#|2T literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/ne.png b/base/resources.pk3dir/gfx/flags16/ne.png new file mode 100755 index 0000000000000000000000000000000000000000..d85f424f38da0678471ef4b3dc697675118bc7e0 GIT binary patch literal 537 zcmV+!0_OdRP)pTI(!tjlO;rIXl@1HV&)cpmDGW-GR z`3+L^2aNvy`v2$G|KGnEMPz|W00M~d>&=s#l8OvKbwEpiHvESG2>tK>|GyyO9|$ut zvpzk42q1u17-V!9I61+pfvQ08|BZwH@16Yr=jVTUlmA*S|6zcEk@1g`6+i&7`~&$E zYA%%V^7j8zTmS$3{hyirzos*?2B2bq00L=%yMh7Y5+V8jy0-s+|NJkm_8$o_f}Hjb zAb?n|yt|^zto-ZmuYW+t0)q+&<<KJ>BgrQT zRQ>1Q-#;J~AoS`6pHRCwBA zU~p!DquG0BzkdJv^XJbWKYo1u_VxSs@1MSW+P$@#L70Jomw|zm0SEvBhy{qNbE|>m zzkmO1v}^=;1(+C_zx@3C{m*wPUMbGM98Q`}5v}3B|NZ&>_xGmUO#lG|(!jv*|H=EO zfB*gc{`33)|Nj{n|Mza|{r>BFYe?(AfB!%K_3?Y%L>Z^l>!7{V2qIffI$#e zz5f4~?wt{_jNwA=k=tvV8m;04hxH1ClNsp|jaD0d_yUND;Sa;#|9^ps{`~n3bQJ?5 z!?D}Pp1*tk?A@~oJ0>vvX8@W7)C|%C)&LMdARGSt{R`y$`S<5P0|@TEy!-p_?>~S2 z1lj|1A`hhCuT1`^U1^@yK06yzfAV)~#?EnA(07*qoM6N<$f^cITh5!Hn literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/ng.png b/base/resources.pk3dir/gfx/flags16/ng.png new file mode 100755 index 0000000000000000000000000000000000000000..3eea2e020756c41abf81f765659a864c174f89db GIT binary patch literal 482 zcmV<80UiE{P)E-@kt#fq(zr{dlL|rVbPb$^K$sU||3VAQpx%4ArjH z5b1ya|A`BUvomopF#HDspdkBi_LzW}KMcQr|NHa%@9#}BHvt3?3s4hK`pMU)fB*dj z0+88E|KR{Ac>Ck+U;lpn{`Xs!M;2%gKmf4-G0FZ zKmdWv|I6_A&;LJv{(%shYM_N64Szv401;3FKmf4-Jp?oxsQb@fum%PU8~*%)I0>i# zs2CuCKpOsn%?64Bg>X9QKhy?*00Lh)xZD#`v33$e!wuw~|G$AI0?h>~ z1_&UqlR!#;Ll9OQ{s1-n2ZahyF+c#Z0Amdp#**BUAaDHn%gD$G3dPzV3};X@Gl13bFaQJ? Y0MmSSAW;3b&Hw-a07*qoM6N<$g7#LQDb&XuwlP!fzJKM z`1`}(|Np-K;|B=>MS!;cWf13KY+LvSAb?md?)rCHn)&`aU^p;VI>1V00D#b-){yc34R8!1Sqb680000@|4`Xj5kLTv#?55wQzKoX38|NjLffBpXj6#2y{D-E;(Ab?mHL=FGT z$TP6>fK>na1GWK({(upf0nrSU5*Gz(00%w4e}91F-@gjtJbOE500a;V!?RECzy5mt@dro_q~YJM-#~SLe}OeX zNT7y4|NilCvNABd0|+1%hF>6clER!2lYo}|1|zVkK=SXOfB*mf{rC6ZKVbL)odgg- vjKFAPVE6?_e~=h|kVO7~qZmRm0R$KTYszPUy89K;00000NkvXXu0mjfB$dbi literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/no.png b/base/resources.pk3dir/gfx/flags16/no.png new file mode 100755 index 0000000000000000000000000000000000000000..160b6b5b79db15e623fa55e5774e5d160b933180 GIT binary patch literal 512 zcmV+b0{{JqP)O=a{vExMP2%`MCSoB^FIcLe_%lf;|~%E5I`(IQNh}3Ao>6Q|DFUXMn*>AqQd`w z|1kXd^B;tM|Njjl{{hM0zwd6?1Q0+hV1xeud-4=Wy?p-%sO`^#2S61Jzk!N?s)6X& zzhA%p|N6}=D+{y%Ab`Lc{sL9~1=0UN4*CD*7s%9KAf+JHKs~=eB-8KTKvw|-5R1&; zzd&a|ob(5%^Z$Q=wHy9p13+aOpFRNu5F>N&`Tk_-7w>=n{RejQzkfh&Kn{rf10?_b z{tFTZibx5v&dxav5I~H7|Ney-|DWN1$%1FyagzUW0464;_wU~W1Q5$TW@eGxtUvee z3vAf*8|igK9~@*rr66bh|NrkNM8z+V zAV?>O@ek;bKfu6d00KAO>U2WB)$@6+CBT{3ok>^7H@y{~6FRKmalQ{r8#S z4^Xx6Je&%q%J2@E@iKAb=Rv<(vO+e^|@#56B5{*~0Mg z>UitA{$OPI`~Tk`F#7!u z%=q{3H<BYX7n!%ts-g52=?&#%8AHvnDo=g*(t zU{@(f3Lcro01!Y-3_uV4{%5PNloM>zp5gQNALI8Qf4=|z|KsPsAHV+n`1$wy&wt;4 zfzU5-=mP{0FqD1)U3&iJ)0b~Q-+l7x$B&=CVSxxV`w!S3U{3%6(9;Y60R+_W0~jFx z85t(6Ir{$dcL`zMKcF!E2U7}WK$QOlX#fZyMg|5;)aZo7D4hMD0TloQ7ytwk}@P)zKX@%&%DST%gMqDF&nJ<9}^SM9e)7=i1G97Xij+!pc8>s z0}TKw06GH{9{>J;c@WiqflO8wrXNp!0t65X1H*raF>uuoM}q1_&UQ zzyE+PV}l7nR6|1@Xe}f}K_mmn5Fh~%KtLN9K+(a>4Du5*FzA2|{m;zE0Q4slD+}03 zKxJTefLQ+k0*D1@+|Oq}Kt_TL2e}yHXa<;L{(_vY&wh05Jg0 z{{*4}t^?F62l4F%@9_Wk_yrLV`1}4n_xiEzG57obO$p>A_3H5V5SZl@9UBk;0Q>>~ zF#yj00jE58tx;oDUfVAO7ZA^g)(IQ}Y8G-;ZB^s|2r!a55}@Ef&J{K=uDyPxdE3 z4FCZEF#yj011R$m=m{0X((d>7`QGgNy~*X%==~K4{m|+BO$p;F|LeE!5zX@o6aMwK z|0Cnry8?)1@m-dDW`RF^3@85Z{`vj)H~*iTuYX^D_V?HC|LG63e*OOQ`}ZH9+h%{4 zR^kLX2_S%&fc^l6#;?EsK&pTL{q^hL&)-1T|AVLlN&WsC!*d@f`}fa3pay^dVgYLS z^XKpHUw?lCNw6Z2x?f-t$o}(Zg7`(je_wy{{yg~C5U2qlfPfml0Rvc4oChck)CmlD zkWL^2sNoMV9{$c|wex0wa`2z{-@pGE82$nT5F-OaFayIEq`3SAj@n=l%a5DE9w9oI(Q6o;?Ey zAdrT?A3yTg*!;YE_t&FGSk*xQBO~LVKYsuMhzTgoEGG70+cq{OrGLMF<5CR)KqmnN z5F^kJDrIFqfoA{t^Z)mszkh!J|NR@N^WQHZ-f!>?ZqK&!y&{zFIzP0wn(b{R37FH0BS}Z;-(ZzkW0R z`o;JgO8$qifBy!003d+C8bA*C^$+NzU%!${e*gOW>-S%fvmgwhvw&=%Tb23#oNZ?S z2p~`>{R0^fayL*XP!U2MkOb-c1#;`ZzkmMzW%$Pc5I_(c{;*0)g6#S8SB49$^)FDx zACSQydx0wd{{073{+Hno13&;Vu4Mp{AoLGRCWbOF`~tJSfrb9TxDaUu27mwq0KDvZ UcsT?Vy#N3J07*qoM6N<$f`X&bC;$Ke literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/pa.png b/base/resources.pk3dir/gfx/flags16/pa.png new file mode 100755 index 0000000000000000000000000000000000000000..9b2ee9a780955566cc7dc2f59ce175f32d3731a0 GIT binary patch literal 519 zcmV+i0{H!jP)|lVPPN>g8sl5Km-s#EI@faK0YA%?%RKmGG2!N|AD;!zX}Teef|3X z_wWCI{=muCn>GOi5DUcMXP^GBIsf;|&;M~|Oj3M||NsC0d;h_|&!7JP`u*?sum8V( z0aY`}$^xwd2q2IKptK|}gRT_Am!FIf)j$AI2PS_*H2ec11_potVu8EfUYUvEKf`}G z`1lE^`X5*+Sm$r%-@k!200a<=Rv$}~=bu-f|Ns5_|IfewfBrH6Nrpdvs+^pde*a>f6qSrfAZn~Z?Fa+2||AuS*t4lqXH%-ra!^K00G3r z@ax~7e+)2nAoSxWko^y??$?YNza~t8coi7j009Kl08{<<|1U847wF+XP}P60U;n*# z@9*{N{$9Nb{(u|?WHSN*&{SqkP0pSkP;|=6L&63i zfEXEE-vV95@Z%rDuRkCLl>P7efnPxL{(%8d!yj-G00Mvj0{}mHT?%@XEt>!U002ov JPDHLkV1lK4=}rIu literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/pe.png b/base/resources.pk3dir/gfx/flags16/pe.png new file mode 100755 index 0000000000000000000000000000000000000000..62a04977fb2b29b96d01ffef3b88b6bf2ff05862 GIT binary patch literal 397 zcmV;80doF{P)@|A6@UbB2E)`X3x9D*gjYK@dOyv49j-R|ARv|Nb!om5Pi12buAo@&A8j1_q}8 z|NqCt{Qv#?|DQiV^2?@8009Kn!0`Y7lcx-S{{qo}h;n3b`}Y4|zksS4Wo3aj00a;V z*zEsM)xUqEs|Es~YOn@|-@kzx00M{wh#7&Zfj0j6!|?mhe@uX+0cadR0D+zK=P$&S z1T_5l12i2VfWS`r`v>f&U-&gJf}I2qKwu{UjsNuvF#Z0+ASnqp<}V}$85tQ7(W#^a2}2+PDh3E3#;-`R r2#VqJ=b;e{^dbb<+Crtk03g5s0zF}bJ8sS=00000NkvXXu0mjfKVzU% literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/pf.png b/base/resources.pk3dir/gfx/flags16/pf.png new file mode 100755 index 0000000000000000000000000000000000000000..771a0f652254b4e891fc73910aab38967864da54 GIT binary patch literal 498 zcmV3lobsI zohi_A`bB&J!~)dH$ngL7lczwX3_#UDxxarw>LBRX?|;94{rmL`$Yzn1{l&ll5I~Ht zU%nI;6$RPw9|VBf|1(_vbYnFmA3K-0+yDOt{~_StKSoBzkDopP1Q63dnCt(82%zd$ zpFb}6I_2!oo##J&nDhVtbEpQW0tSEpVuGrMivIupee<8UpWZS`Uj1hH_v_am-&g;K z1CTfW0R#{WvT7jw$rQ2Wy6P|4+kZd)xq2}(*g=aGrk)Yxu73al#Db(Bq?4D0-N;b? z5G()RfB&pB<@s4TkY)e;`2!F@EcYcO{->q=ymt>64xqsK^^5b@FIO-F$h{9?`~e2* zUv?FhqZcm%1P~}#|Nj2NBq_=8`#0mCzd$+0-@loGnqiRuWPl>)F9-k?0|XG`aR!E8 ou!#JF#Q1|6-w+1S#{dBa0Kx%7Vg$%BF8}}l07*qoM6N<$g2}Akn*aa+ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/pg.png b/base/resources.pk3dir/gfx/flags16/pg.png new file mode 100755 index 0000000000000000000000000000000000000000..10d6233496c10e52ead975c5a504459fad68ffb8 GIT binary patch literal 593 zcmV-X0Hv=@BjaQ|F{1AU+wpQ{$Kys{`!CTH>0fVKL!SX0Ad1a`1cQJ=-<7ptZmH9SAnX3 z{Q_yQ`~BbL*ME+m|K)!Dcl`DLKS&U$0U&@t8vg$M`{&P}#F!W*N5{%vzvln`{r&f^ z{||ospYrSf)?fc0{rZ3A*Z(w-2B2bq00L=XVPVP4%$zZO`i8aZ($dmav$E#>{B`Z@ zum6{R{h$5&|A}A!9e(}a_zUO_pbY>4IGm#s06-9cg3a4XeYH!D;D>_*`V5R3;NTtr z%*@^Mq=>M$LXVh`5jChqDeaf800L?F_U+sH_3M8E<^KOyQ&ao$p literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/ph.png b/base/resources.pk3dir/gfx/flags16/ph.png new file mode 100755 index 0000000000000000000000000000000000000000..b89e15935d9daf25173f89a36d8111824fda5db5 GIT binary patch literal 538 zcmV+#0_FXQP)N~0_Y@w0Al+04@f;`V3_{@|8#9F=K6XQ9UY*azdwKd1Cc)=8bAo50U&@_7#Kb? zFg*PK|H1$NTnr5Nxw#FRn^&xvtbK0f`#-;cuKxpc)t_H~fDExeq6ZmH0|XFI1NZ;` zGXMXp{AUnj_^>}zDz4B$`$1}#7U0X2MOU=aELU!7sY=Kr&1{QvMCSsj$|2dLpM12Fg)7ytqY zsKMy}yX6c^FZ@4woIyZ63`(G)I*8l(j07*qoM6N<$f~Z~XumAu6 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/pk.png b/base/resources.pk3dir/gfx/flags16/pk.png new file mode 100755 index 0000000000000000000000000000000000000000..e9df70ca4d63a979e6bcea2399263c081ce5eaeb GIT binary patch literal 569 zcmV-90>=G`P)`{xe>ko^7oADI06=l8$gn`UeR2p|@S@&Et-|M&0Ts{jIsi2(+HrUEqpC9EW^)CAOaJl^^9-%lBC8BHP081)#ChQGgo zHUI<=3(zGH+B`^Tu)Z%{q{PpYS&%;j+KluCr=pK*_e;5D)h=t+bKO_wx|Lu6N(?HnJ zN6`lu;-7zgR^V0GaA(7wCwqWF2h;!%KrH_l5Kj8_?>EpHKuhXR);;uSzaAK9KY#yZW@T0p zQ2G1+FVF^n0AhUp{`o&J`0?k5YKbbt8;l4>j(9ExfB*vkhsr>Vq>*li00000NkvXX Hu0mjfu=^7c literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/pl.png b/base/resources.pk3dir/gfx/flags16/pl.png new file mode 100755 index 0000000000000000000000000000000000000000..d413d010b5b097c4e0a4604eba86dad79567ed16 GIT binary patch literal 374 zcmV-+0g3*JP)Ab?mv3iQ8Nu5A{|6C_|Nk>HFfjc`0biay0|+1% z2B@O{$c+Ek03##gzdwHf0*Hl3)etG5lK=vU1?W~rxN0!OqXDP`Ab?mH`1u+7`u;zA z_W#cxhChG)!_n{G|9=A+zrl>(AX#bYe+w4^1Q6Is4VEzI_51&? zUm!LT$@u9L&^Z7B1a=Zw2xL66B2?87%l|Mi00a<712fnG3~)u5+Wr7F{AKw27w8;- z00L=X`u&GNQW9*;Uxq&*os3{386YGO{rw9;K*az7#P}5)xp2gQ%0-g`0)PMm0MPYZ UsK>Njp#T5?07*qoM6N<$g4HXSwg3PC literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/pm.png b/base/resources.pk3dir/gfx/flags16/pm.png new file mode 100755 index 0000000000000000000000000000000000000000..ba91d2c7a0de26e554979f6351d42a1a4e22de3b GIT binary patch literal 689 zcmV;i0#5yjP)#D@XkmAv!xDMMW8-mEZ&mK%|%B2@pa*J{pUD?(_ahBqlG}*TVt; zF#yj00{;H~{{a8``T70x^5Ww5-{JLFN2dS#-{Io#@$TjE?&8zZ_V@JO>E`A8`2YX_ z`~rx{;oS`3$G61pUY_{!-0$E2{{CbX;QPSJ^3BEStfg-V`n;-q6+;t+Xyw zOy)sS^8$#8OF-b~@87@v{bTs||L?z_Zq~=&zGIaZd&b4_{m<{;|Ns5^`sL5xKflEU zUjXHSP67x3F#yj01nBVe84eEr00I90|NZ{}FelkBB-0BC^O2xB85HWz)f)HsDi#s! zMLEolpK<^Iq5=Rh0M7pb=>Px;h=2d#;^FNBZtPGJ5bKP1n*{>+?(qio_5k|){tF25 z`1Sjqtv%A&PR-7P0st`p&i?}b008M5=kFQg|M&R&{r=?U4x6PnhWa{`B$w z?CApk{rU?E^8f<&008;|hy@rKe}6M^a>=kt2+9et{QJXr>zQ5ua`W#$8JQS={rbi5 z^Ctr{)6XBj7@3%V17i>%fEb@MFnj<<;{gVSbOv{z8Q{qN1r~!u@ISB;HgNQF0R$KT X>6#2<48ze<00000NkvXXu0mjf$fQr4 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/pn.png b/base/resources.pk3dir/gfx/flags16/pn.png new file mode 100755 index 0000000000000000000000000000000000000000..aa9344f575bc92f4c1a5043e6e7d0a8b239daa64 GIT binary patch literal 657 zcmV;C0&e|@P)$VEDzr@CQtS7ytnPF#yj0 z0a0(~eP|Fd7x&oU`XvhO+V>M05dgm54eRCe)!y3s`vCp^_5Az)`uqj_{QRhrlmY-T z0M7pd#W4OILofm6?eh2PFCO>E*7Xbx0@lgN z0st`p&i?}F01o{F1pxvB0QdR->g@pe`}O_>?Enew{R9F2_ajBO3l7@{2K78Gz9u`z z008^~05Jg0{{!Vds4FN77!dx<`5YAi^1B#F4D8&$5I)oT72fOU?&Jm;1k~m5*82ws z?b$fe$;$!&F#yj01PbEP9OVUy$0!>9?*iHF&;9=9{2wXIjNS}D{P+g={1WdM4-6DF z>gCe?_5uI^`T_tk0M7per>)2uHb&;=(#87${QNQl(a`kw{Py}Y1nctu{`UwC>ihis z2n-DS{QU(1_5c9-0*DC|aR2`P{`;Tl?{DV6zkmJy$H?%Xjq&fFKfk|zXRCbma58?r#f z00G1Tv;`<3F2eQa&)+|P|NZ&>@AqGj(m#Ly0)zk56?XydpHmj-@bfY4J_0oTA3y*x rGBBhgM-@1KAF z|M~a-&+mVKfs8*8^zZj?AObQ@tXl^VK#U9w|7)um9zFT5!1JoGnu}M2{r|uJ|AC@F z;y(;9F@d=M{=L6-3m|})KsNsS&&$bh^PO0375Ag3EPt6;7?_!X=sz3*^#j#0Gyh{@ z0SF+Vlm3Z`F-Ar(?BDbM+y#c5od5B%>y$nn=KcNZ|L>nr$AC#T8JS}%RsaMLPy>UR z34^BAe{Qb-hmSD)`~82~jewZHH;sOtVgB{~2T_Lx z^M7~ue_6TzObGu%0nl7VM#g8?t^ouP$PYjMFazDG!uzbThlgL98zlelKgeJZ;~z*Z zSPxJG!?$k$0R+;(`ulr=6P)M00|Ni~>`!`VeZ#eh`fLE8Q){QmQQ=eGY$|NqCtU}^v=1iBd@fS3^8`SJ7r@8ADF ze*C{^(f_{w|JZZ@y#o+HED**2KY#i6{~yEeU;qEJ{Pzp|pOucqNnlF=0*DFdB%s0n ze*I+l{{11(um4^iSXF}z{SS2YKY#!N`GNV*AE2Jys=p_Au>JnK{@0e3zk%WO_xG>A zzkdJw^XDIk{pa6bWqzfjEk^+Y2&CaX+n+VzlIN6JC4s^J?+-}zKcEU=eEj+Q{|`_P zFrfeb|NHmfUxq&n00G3<$-qz^$iN`P!0-!({va{_z!?9)Bm)CLfB^vHpj0t%_B3$- O0000op82)aAGO;3n0AgYI#891D4N?IF|Ns4E{L7&Dm*MXp#y@|U|NLS4 z{rmr)KmTFmmra`h0*Hly38?u0llM=#nEx6H|J4!x{U`A6pVzdvv{Rd?JIrI9L zs`Fos+0`Q4a^C}Q0+k5A1KaQ$>Lf<6lK=vUh2aka(D+|}f9<^YM_B9kC$A?0Z|}3+ z`ptao7t>dSY6f5^0o~2O01!YR8-T_G^}PA>yZ7X8cHUpx=KlJ_{+sC?ST#h$AD{+c zSpNn30U&@_7``$5{_{tYU-I{#-$2g*Lz_YNHw#c5FVJd`!65YaF9ZRd1Q0-s48{x$ s?-&?Px# literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/pw.png b/base/resources.pk3dir/gfx/flags16/pw.png new file mode 100755 index 0000000000000000000000000000000000000000..6178b254a5dd2d91eeaa2a2adf124b6dba0af27f GIT binary patch literal 550 zcmV+>0@?kEP)~nkZ zGRMDC%7~XK0S0Tx8Wd7-QG59jKr9SQAk|O4{{Q=*0jSzY^rW5C9>)KFc0aM(`^fh9 z|Np=Kfe=u&EDs~YzkdJ$!~!z=-~YcrJO42FE6xsAYGq`2_Mbt_P-yG_e|4Mhx&31J z|LZSE!|%TgKvw|-5ED@OU$BE2n0|Z9O=M(v1mpqrFfl%gR9?uy{Oi{rkOq*RfB%6# z1PCA|pp${Bfd()#{N!P|4fj41<69Aq$E=K>;Tryc4F(7xpbZRv|AD;q^*8I6-->Vz zfB*5n`o{nM2Peo6f5F}W+3*h_fS7<7;^vxc*?8?`g7w0kCk@cHxaHDByoH$n$~K0fYN5BQR!wAqjL2Kmai^lz(OTgcO%Q oK%!9YKcr{|u^AZn7ytqc0H_5zuk@Q*SpWb407*qoM6N<$f;OS^T>t<8 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/py.png b/base/resources.pk3dir/gfx/flags16/py.png new file mode 100755 index 0000000000000000000000000000000000000000..cb8723c06408828ce68a932ff472daabecc64139 GIT binary patch literal 473 zcmV;~0Ve*5P)@|4`Xj5kLT%`al?B=W5I`&pU%&omV`KRD53KJ$2txq_ zg7fbmh|k3I@68*40Al&@kBy(1nSq%Zss!k?M~{APS@-YvZ#JJG201x|0gQ}qez5@r z5EI0wa6>`h%cteq@9Mue|Ns2{KQdro`19u4 z9*F+^0|+3-w;#WAv9bOIX#?r_2Xj8qX@CF21pWab0}C_Lljko10*H}8@M3d^)Z>@G zf!6*0!vH4#gGo5!|DS*V{{HzdC&9L6!fAj26p=v+03Zy*=I{f8|9_}7o838uP_pBd z=z9{Sra^iHOE|+IC{ z-`~G~{{ZRVfB*dX11A6d`CYbrEkFRVK#Yg0UeQ$d`q2ZhA|Uz&)bIy{egR1#X&Imb zfB<4bR{ihazwp{dkXn!mkfPsU#_wMs1hfID1|Wb~;Esc6TU=EJGWFLlunkbN!Q9_} zL0)432p}e)sSwo=4bd$f5a~a^fBpd(3|0LbOac`E1P}{Q!+)sq|NsB}pI=e{a>g%& z)4?|U{s;0mNCQ9sG5v!Z57O~Jp}QY!5N0Be0)lgG%);U`26kn-@hOg zU%!6+4+cOs(0HIde9xZz`}Onxub&LUB0x(30+2WcIRJn#2ut|?gWYu1Cf+!-K%B8# zdf?1WA}#uZ8oj7u>$I1i0Al&`=O0k%-@icgAIJnM0xA6maSq6BK-ECw|NZ*S`0Lj% z1_pot6puj;05Ax`F!=umqj7^frO?t|3^&I1kxUq9yECc+jQpY84SWH_0#pxl$?v~F z@*hy-KN0|X07U)z`4{NpU%#2aHUI<=%a31wK(7Du52Oc(|3O^?R1IN+RRjI-n*kVB z3=9AP#PZ|EACPLGJ%9cJNh|>9B%spYzZw7h1%?tp0I_@ndg9MNE>313@6R75NcceF zkr51-#U+7;F#`Sf7i0rK0I_`g_NQ&Zji7_t0d_@@ozArL?Su`s;*Q{AKpRQ~TD44PX+*q00taD0I@Lq1k(S2nt`tR{g)9*1H=ZfhCe_Je;NM%1^NLXfPkU&2dGq1gcanC zzsyWb(hLmW7#V^70~+_6f#nZ_(jSmgFakOWAb=Pd7`8Gn`~pjZT=;x%FbfOAzdzu3 l1(F{a{)I#17yR-T)##NTdjqb^wzQ(`1@?t)Ix4MUXz556teM9A7Ic zq_@itH|pv>q+zrjZJ^Hx5bj=fD{5McI3ol<@^-l_@~tZGV7p>1CU&qG~{YccyC-q z$8~P)6sG{nMmQy85K$E6L33rja$x-b9$ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/ru.png b/base/resources.pk3dir/gfx/flags16/ru.png new file mode 100755 index 0000000000000000000000000000000000000000..47da4214fd9edb383687c1d4f84fe8b42a51ceb2 GIT binary patch literal 420 zcmV;V0bBlwP)X|NRSO0LlM<{-BURBqYRGSojej zfLOL~|EH_V_~;P>Nc10*D0|Jxss< zFi1)Q<$$6LU}rIc*dU*QNFV}+9T))>0|XG`SD?F)5CbX~O$rDA0t^5@iDe$xIAIn5 O0000N_~0!B1ZtR02zJmAl3i>|Nr}+@!x-t zvcLa8?7#n*fB$3p|L;$z$Rx)9zm`4EX`B2HAb?mPX21FhQ~^@@2dMNf!=L~E|NQ+A zWdHd6KUK1c=hsc9f8Rnyezh^=0R#{e(Ek5GMIci_s{j0D`2GL?@4p}ozrlKzzsUIh zhw0@n(cNzYfer%*AeP_1{{8vS`0Fp&84w#lmi+$#)ARI~X!Y&+KyeWsW`<9n00M~d z^G^m==F0#79{mS71ZX;t`~_q%fY`tPf!Mzw;*3o4FJA8j2p|?NkT1UdXZrG=;TOYy zh@M|qNhT&CJ~jq`0Ac}pl#vl6#K7 zFA)9u_3syi0VMzY2QmHtx&Qtu@&7&0&HxaAAvs6^7=(cU7?W7&6Z-$piRe`dyDK`^ zN$WO$zWL=wEu!PO?Vu9@iVSM&8cWvf2p~p=WCn&G3_$lI&>tl77dYY}Tp)vm0U*Et X__=7oxWDB`00000NkvXXu0mjfV`BRN literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/sa.png b/base/resources.pk3dir/gfx/flags16/sa.png new file mode 100755 index 0000000000000000000000000000000000000000..b4641c7e8b0dd79aafaa73babdb525d3d2dc6a8e GIT binary patch literal 551 zcmV+?0@(eDP)4!1u&@QJ10&`rk^HbMk8Ee|uIe&H zS+;4$DbWCt7$DsBz5oJg0IGiW@flDZ69W^F_wDDmUw?kFvatRB^XvPsAO9KtfBpI8 z%a6}8Lb5=`00G1TbjJVx|9}4ZVWnuJEUfzZ$EVZx<$*voWzTGcp~$d(=+V{_?X+ z3y#kPS_RYq5I`UeU<=TsD9Bk~@o?qi&=DPd(?v86a{(`&&3I*E&g8|Wo?Sn;v*0j086Wc~d66UYT>00&^E24DBZ$$%)DV9SRUYEY{Wn z85tspN%!Z^Q&_X+!-^Gee*b1;`1hkUW~HJ2(d(c7|`w2)m##KhU^#|s1eh2YzMVW-Z(;)C{QJl7?-Rp6DTaSP8U8UK5I_L2Ffe?nu66~hU^Xzg zV`^IR|NmbGhChsd{xGln!xZ`Z|DQkqe?!SHn>GOi5KsdU{eSZ0I}_6%bMu4$|G#2j z_zP0e_xu0e-~WI8{{Q>e|6jj=B8;-KKpOx8hy`TyKZd`5nT(9?%F2RO|M~TQ@}K{E zz)C@?e?v4d{QeEp01!YxcLP=bXJGj0<#nFn|DXSVfvSK1-v%}nhwkOu|GvKejg0<-0ptJwK&1cy1oE`H<`Z?5M+~$7{9gq& zn~(3mv&(;P@Bi|05T(EW{(k!9>4UEid{_Ab1OPDr&i@1e0Q5gX)c>UW0I2)_6d3&w~i*%}NQ0G05Jg0{{#gAwk6j%|K36Wcrx-Z zDBuV5-R-~I;@8;l*yr}=_xShx{`~y_{Td7!{r>#`1^@zxvDKIVAJ?B1c2ZXvZZlkB uU;qZ}2Vg*eW0eWa_yywvNgf7(00RJ0?>)A@UfIF`0000~{{6QA+oUi>E@sC6|Npy9I|mRz%!e*p z2Rq5%zu9WWBC0CAb^-aHZc7E^YzcK`=8X^WVaOP zAZs{XYh)0l^y~V&U!Q;f1_jw4fB*tH>G!)IzutbUPS7xun>*B|^YmYFnaxh5oFnsv|ie?b{2U7L_4Fkgm jhERtq_4+^_K!5=N1|KO))1zs%00000NkvXXu0mjf8-+Z0 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/sd.png b/base/resources.pk3dir/gfx/flags16/sd.png new file mode 100755 index 0000000000000000000000000000000000000000..eaab69eb78776f8593b41c8fdc3fd65a86119a0a GIT binary patch literal 492 zcmV`tbb&P~tyW8d(D~GxMiUp8x`gh2bB=pZ|ZjUUI!&{yK1G;4d%$ zIuA;MS%3cg{`2Rrii*m`ix&X`h=t(`1IH^)u0vdsLXv;@{sQG7;18Jf2Mqqg05F6A i0*HaZmVqPy5MTgGElxU<64PS<0000a|fPuet^$h(7pHv_{jfB<3vn*8q{15ov!pR5qo|Ns4BVf^v!57RHO zo?l?}`yWs<(7C?=0*LYNK?X*pGKOD3v;Q#s|MUOfZxH$qCjb2cBQWFtZ$@_cPkRpn z1P}|u9|n-AAQdnT|9?TXAyk7H4FCQBl>h_~&`AvcLF)bhMS(&{8jwh^2qVzve;5D) zh>=0RIIAq+{+o}$pxEl(3%2T)`P!1-fBt~{@Pp~sA7J?W`}60ovKZgl)=2;X#KQ37 z&mWM7{{H^+4`$e}UqIEMAo>Rk|KALM|1kdh!vsX^3=B^I0*D0|DL|!?{M^6*VPKPH z00z{*-?BnHps)wJ`QKllIe-8D1EGJQNCgNWMh3}bctpOPvlbWzK!=K^+cJPc;};D5 g19O2S13-WQ0NlBGh$rR(5C8xG07*qoM6N<$f_QiWUjP6A literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/sg.png b/base/resources.pk3dir/gfx/flags16/sg.png new file mode 100755 index 0000000000000000000000000000000000000000..dd34d6121073fffcb2fcb5b9402b3e6361cded35 GIT binary patch literal 468 zcmV;_0W1EAP)dtOYis{Le*Dj#JuDs`KNc)tl9OYUmifJZ zA4uJ=-~WIA`uFP>kj*SB3$z3vfIu4l|NYA>FaP8D^M5;ba1<8<4f|GC2UPm+H&ER# zkRGsxe?Y{*01!YRC;dKnkj2`X)zkCW_8s5b+Wvn23^5y|0jv~A0#!5q{{4%A0U&@_ zfL8pya^=_l{r?#l8F+XY{;)G~as30ko(ZTFY%s&0Ka9WsFiJ`S6$1niy`;Hnv5 zfRT}r0R;fL{~@sn5I`&p|Ni}W_wFAQ`~gBVzyJ~jk&qMs5MThRyiZo6SsHx+0000< KMNUMnLSTY6dB!#X literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/sh.png b/base/resources.pk3dir/gfx/flags16/sh.png new file mode 100755 index 0000000000000000000000000000000000000000..4b1d2a29107be96413eb86e64a75ac7a3ba5793d GIT binary patch literal 645 zcmYL{Z%9*77>Cd9?woAXO+#E-F%m^1b0Xy*Qky9{B^@hJqB6}jOKKPc70u1CS|Ug( z7>SA^1`5-}4+VvY=3G*k2%(8O!OWTIn!4?td(P>GANugV4?p-l@2B^fCONIbD;IAODX_{rV|BCn_NC>%qlWoHrzH=l|0Y^Rhgkwr%>N3 z(d)FjlCqjgyY4&yRH!;rb)|Z-v~HjxIkvar`*JLyzxBc-B?Ix`3*qGz4q3JAd`#LY+Xw^k(ph!n`d2H7`aI`Eh(LrOLs%9g zj93;8ws%s88WHkIqXqnSf?YSjh=@dF-}4L7dS0HFB@iNj8OY*&4>%Dn8t&*i)aXz6 zSX_wQ?~e=9UcwhrAtAf8XLVoTbE5+<^|-KK=D&>)yX6u!zrPCrbEr|4Yi(XyIGTQI zFEDsraAY{)DhUd*DN;Q?!uSxvkoT|31dF#>2L0DGeRcNZNehm>xm~}-9q?gtV@Qz` zv-lB19|m}3LHcg92}TUOb+%v(0bnUhB(5rQI9?ZY)h~Hw=%2Au&~WB@t;^kVE@F0Y z%=8f1ZN}R1MniiNxkJ!a;3!XFerfimE2A;1XJChGXJ=)MAVRubE8WFo1T(1Cmhdfa ztzC{Qms6asjkstFkFp5L#maeek84Y+NtW^Wf=SRytjpC1=BCX4NH^VxnQ`+YXocAv zR?lKskkKZN7D>{S3>4;4+gPYYq0_5iq@jsB^}M0yMT0|p`lM;R_dwbVrBg^4RRbsq Y$WB%-43-yHbAJTXS^1gPjGK@C0`m$%7XSbN literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/si.png b/base/resources.pk3dir/gfx/flags16/si.png new file mode 100755 index 0000000000000000000000000000000000000000..bb1476ff5fe8e0d3af4fc6bd11e513d95fd9cccd GIT binary patch literal 510 zcmVm9@#;PEzrU@Gx(rNA|FHo^Mn<3|00G3vEO>ZAhtlWIf1*N!=PZ8p<;&lH z{~7-L`S<7dzu$lU0~x=8==VP$LqeQ==EOq)0mSn6{g=m2e$<)X`O9Zpu5&$Np~P9Kn=gZ0kf<1I-4a zUtk1c`~{K>fBu3(0U&^Y8d(1RW7^4V^6LZG89>!QBmXe{`pfY9FT=0Dj8O6)!|#7g zK*az7#L~(TO=a{vExMP2%`MCSoB^FIcLe_%lf;|~%E5I`(IQNh}3Ao>6Q|DFUXMn*>AqQd`w z|1kXd^B;tM|Njjl{{hM0zwd6?1Q0+hV1xeud-4=Wy?p-%sO`^#2S61Jzk!N?s)6X& zzhA%p|N6}=D+{y%Ab`Lc{sL9~1=0UN4*CD*7s%9KAf+JHKs~=eB-8KTKvw|-5R1&; zzd&a|ob(5%^Z$Q=wHy9p13+aOpFRNu5F>N&`Tk_-7w>=n{RejQzkfh&Kn{rf10?_b z{tFTZibx5v&dxav5I~H7|Ney-|DWN1$%1FyagzUW0464;_wU~W1Q5$TW@eGxtUvee z3vAf*8|igK9~@*rr66bh|NrkNM8z+V zAV?>O@ek;bKfu6d002F*|Nr~{=Pyu%qcHbB24G}l{PX7zKmY(S0M7peLS*D^UKK~y z+6(XH|9gD^r>6bY*OZ>+`2GX^{Qmv@{`~#_{QUm>{r(dW1b1xK0st`p&i@3&%J4-( z6Giy=|7vRh4-WrbUHx`??d0*<@CX3>{QLa=`~Cm?`~Ld;{u~zu0R89!i0SVi2B1U! z{r&fU#+3gbKmA|6l!@v8=U+^J{{8>`mjUR&KfnL~{sUtC1qTg400I5L26X!4i0my} zo;{uZo#CfPX{7DT1DwDAf(-fnkMZ|^ra%9I0mS$d6bftr0mQhUfkCOfiE zM%HqlKU{maemr>kAILSo!3gZ8-+$N@WcKe}3J^dnRtyZx@9+FOdynDWy$P0%j62V; zZC)?>`}hA}zy1SB2;@n0006p>>h67sJD!pI8@uK6+#GPW%ce@CEFZM znTD)%K!F4J_qpc@AQp(ZPk%rA2T{TB=kLG2fBygZ4O9eD_xsnsUl6u5yEM=SfB<5# z6|+@gR}o|u1R4pn+XF1YrQf2oylS zAbS3(sBkhcTmc9mV6grHN=r(zLW3F{=D&YK84x>x_WT70A}|U80*H};VI?9O(a}F7 e1_Utx1Q-B;QgQb4eH!Wj0000PEol7!5I{@}e;EG$`~Mq){{FvoV+so& z6Zek;JYV*``O13q$!wq?2!V|I&+z9TKmf4-@!$W9Km&lr1Ie!(IeUNcyZo#F`{&0p z?&{CqnEw9%50U)~((nf$fIu4l{AK07*qoM6N<$g2hARp#T5? literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/sn.png b/base/resources.pk3dir/gfx/flags16/sn.png new file mode 100755 index 0000000000000000000000000000000000000000..eabb71db4e8275a5bfb7b1b8f3a8374d50da95db GIT binary patch literal 532 zcmV+v0_**WP)6{xSen|M~Ox&!2yPfTn)={d@hr-#`EU4p90fz>J~+=oo+i0%`d3@9*!wzk#ZO z2WQUEDXOGe*gO;$t?-?1~^z5 zels!xNuY7SApXOk^arFAjDSu82p~p=WCoxfknArIdOZOgs+`19}IpFa%0{xSUi1L7diFBr+f01$veIX40Tgn<}np4MoMn3N`o$god9 zrkzn;+j{#q5F}xeh49xZuI$05IKi0v3Lq917Le*!UxBJYN`Vr8|1$jj50VD5fvSOw z-(ZF~46zx($8#~-kUKOh9u19TNY0I~dG z`1hBA5y<}g_y4cI3}({*g*gAq^Z#dL_#dnH|JmpNJMaAe2etv|3x;0|00G4G>kr86 zzYquf`+xk=e@^EAQat}9xc>97{@;He<|?3qzo3u+2q2a}APrzwf*tnl_y6c6m z5?7266~G|=0}2mdsDK;{bP_-SF*1~XW%vY(NDyK`u#uw~6h{mUJPZH<1^~BhckWKq{Jk|L6Yw|Nrm*vcLXk{sL#*k)f0!)jRF?KX6FHLLC_7zyJOQ#RJf}AnqSv4E_E0 z_d>^cfB<4-C}v>z1dGUDNRj#r9OZBkNc8hC00bBS^Nnc?6(4BA00000NkvXXu0mjf DM=x{`~^7feaw| z@9%GBrr%pd7ytr@3Fu&;D>$G0;d%9&ckUlP_FsJLznOpkI<);49~%fU|NOOg<1c>p zU%YI;<@gu?0tjRS1JJ?0e*b^_hvDg;|Nnpg`SWY#%HJzjff!!CzZWj}wP?w&U%!5b zMg95nhXEjfKpOu4{R2W=zZm2}8km@V1qJfIu3a z^ZvQT`ny}__wU`%Fad@Sg!~P3A(#OSI%WR9r+OFw0*K`e1H&7RKZ`vj#ee<&!}=E_ z2M*0Ye}N7Llfc;c2aF@2)L(`#3;+SdxR!w-xR`AxVx?>``QKoX4p z{r>$=Qj`^FFF*h>?mzuiS(feBuYdplGyMPm{~rVab^il$89+1;fd$yvm=2wM1rR`t zfB*hvWMl+7=|4yZ16bGpcem@l{$rO?srZisfXY67`UDU_ED+y9gdmKw*T0{<`x@v9 zlkZkl}Tegi}1FC>)y z`~`;fe+5al?K4jS1P}|@5C%z67NEr6KmWj?{{J^f1u*QH|Ne!BH7L;kfnp0FfEXE= rk23safJY>Z`~zeELt=n*00bBSq*!cC{}>3t00000NkvXXu0mjfg_GrH literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/sy.png b/base/resources.pk3dir/gfx/flags16/sy.png new file mode 100755 index 0000000000000000000000000000000000000000..f5ce30dcb79b443ebc1615fe4889cc26e2d762b1 GIT binary patch literal 422 zcmV;X0a^ZuP)@|4`Xj5kLT%`al?B=W5I`)SK7Qoo3V-qKd5l^# zgv$taFhBq?zJ2?apPwJU>mjm?jEr~g+yMw6Mj$IKE$!aDd%wZp7Z^YoAQH^_^XK=U zKYvwJR4!h;2oOM^VEz63kEEm|Pzoptl!JgjVAdZn_zMF-#Q*_BG6D!N0MDLEDh$KY Qwg3PC07*qoM6N<$f z|Nj36M1Mf!|33`>e*gaqWCO|HKwFtO#a&sZ0t5gt0M7pel4t!zdFAutyc%F2ByLSib7d z-@iY8{9s{WsjaVha_-{UlG^LGvEO)A^**!$6$1ni3ljqaFhGRYPy6$qf&JG{kKey{ z|N8ae_ixs}{}``bdDhkT?#VOp#VvoBm>H#|fo1~)5aY*A1~#Xrf1jTKgW~`H-wePI z{Ri~aZw6pM{r$!84-_k)u=@Ltg1)Cf2{xiF#iKZ95W~`fDE7~ z|1pDN1{?_>vH!pR*Zxoe2p~qo;+=0k{eVOy5dHe~@Bg1a48OqWACLsaJOfY!7)!uZ dz{3I%U;rfUVNTmRI(Yy9002ovPDHLkV1m_xKPvzL literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/tc.png b/base/resources.pk3dir/gfx/flags16/tc.png new file mode 100755 index 0000000000000000000000000000000000000000..8fc1156bec3389e54d3c5bb8339901773a881e68 GIT binary patch literal 624 zcmV-$0+0QPP)Mt z2Fbqp@bUfi_XiXZ_x%As_WHU2H1hfc9TM^w3-JC0{^0Bg`~MgK0Qv%mWs{6kqN+Cc z+b3Uc-enXLWmi^s_2~6APR{Qy8GilxQ)j#p({t5y7`^LQ4&lw9Z0Ra5^`SSP!?%<&3?fU!$2L%N9{QCa@0Qv%mW$D2m zA^~iFet$Uihac>@UpF6ozx?O#ufL4HfBpRUndtzp5U;>@#TUPR{|1KG4}bt-0)`aO z`@jDF|MM3p^6S^{zdwKf{q+mXVfa4fgq7?27ZxvH%|34Sm*EEk!#{ukVgYLS^A{)$ z3^fq>3urc&4I=;kz4MwgW4X`2zkh%J`Om=vauPrQ0X6*k{pY`=2p7%A_P)?P zUwuVdAkKe=-@h3}_C6p$AOxEwQo+UIeHT5%mg3lYGL;@HP(LjqG0$?6F}(Ht8A z0K*^*BsuTDFa|;zm9Mc;PRcq|KMMBO%8|{GkrU*a2x&r-3HS3`xnqW1|R~39RolBu`vAj19S<{HjoWK z4L}tj8-Qm20eTwfuYbROLyY(bwgDi3SQvf*HG+%>>H*pSauQI_zkmNAP67ugNCPlf z{{97O00g6G8FFbZ~XHln?_bqJeH^V)*lb;YTJ&0)m(r7ytqc06HRil3NF`RsaA107*qo IM6N<$g5!7R+W-In literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/tf.png b/base/resources.pk3dir/gfx/flags16/tf.png new file mode 100755 index 0000000000000000000000000000000000000000..80529a4361941e01d1def5d581bf2847cf99fef6 GIT binary patch literal 527 zcmV+q0`UEbP)KfiwinSYl|od6I(APxT+{=azr6>87_{|pZw{QvzM zh#vfW|M&NwU%!FG-`~IfN=xzq?EwhD!Wi2C0Dv&)|Bp?Zs+hPi0R-LQn75%cY-O8s zAPsw;Q!9X27=Hcx_y6DDzyCn0!4P6RP{Xg^fBpb%_yyDhbQs7f8-Qku33L4cS@IvK z8OZ(n2kOgTzyGb@ek0IRW9ouaN6$P0x*s5bfH4)06qlIj4>;1{Yyp4(0|4dQTo>gF RMrQy3002ovPDHLkV1fdR=hFZH literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/tg.png b/base/resources.pk3dir/gfx/flags16/tg.png new file mode 100755 index 0000000000000000000000000000000000000000..3aa00ad4dface0a9c23744ab451cec0443f187bf GIT binary patch literal 562 zcmV-20?qx2P)@|6mN}b_RwI3=Dr@=ogG+VE_mq7La^(HIVqv%*^=nCj$%1|9}7Uoj(8m`RC6+ zAo~61@1NiQe*Xrt|Nh=Ea}z)Sfi-Y&{FjhmFg0aZxaj}$=L~=U)(L)O`TP6-zu*7= z1Ib@N^zYwqCU)6YF9v`BVgi}{>lcH)J%gU!|J)p)>i@rg^Kt&>WCWsLoQyxgk29dnvBpN5vQb0*LYVQ3gi&tp7jnGyMMp z@*mKbe}4Uk_!#8f-w;8De}5R+mEP<>2M|CkH{LKvi2wQh{WmZi827ytqc0C8?ZF&p#S!~g&Q07*qoM6N<$g49|K A6951J literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/th.png b/base/resources.pk3dir/gfx/flags16/th.png new file mode 100755 index 0000000000000000000000000000000000000000..dd8ba91719ba641502bc7ffda16c25dc71b2066c GIT binary patch literal 452 zcmV;#0XzPQP)@|4`Xj5kLTn#2^O%5QJf({+!S7KyMr1NSdb0?wsyYS6cNVdko7wub89?$EL;)x)00Ic8;m6; z*ldXL$Yz5{poPB}7`^}m5DPc2nu@9r4=+1782$pC1a=$HjDKJ@i17#P6G=(#Q>V-T z0*LYF&!5c9%>VxV!xcCX0F(uW(%ZLh0Ro8SA3Hl!NeKhQjeq|#{05SL7=Ql;MhF4{ ujRQ&nZP~jQAb=RZqDCa1IEDa#00RK>mSUL#9?hx%0000(5Af|u+{y|g&!S9Ft%(8imf-XR*|Ns8{XO&`< ztN44b9;zJZ^?&~W0*LYB$B#TbJpUo){|D*(`>^x>w|gKB?9z<#wQ%E^n3(S0zYh>V zEO6uD3`W^f29Wmu3`mZF`w$?27#UO<(rVJ~y}I}N&+p%VfB*XP3y6U1Uw^?QNbuL6 zzrX+d{i`Cbal7Zfib@b53s27mx! mU=U|u;Adc9XCM*)1Q-C-v^a{iiydVE0000+lNu{Qmp=|FW6D0*D1<1Ovm9m%kYQ|7p*Yo3ikU z7~kiESLFZv{{Q#iA0zqwf4<*Xu-*CD8$MYncA&8U0mQ`ckKy0n|9}7f|MB&2MbDkQ z1j{KKBL!IA2(Z7F;(zkuBe#mo9TT;SzkoLU{s(jwKmai@{QdX$=kGt?etVi7(p9*e z(|o73K&5wiaQBkXEB9so{`tH8jIplb^d$ZPi5h|uLD4*o5RnOS|{Qd{@Cr~j!0D)}y0}8T#$FHit{lE#dc*g~k_utsL zxj&Wpto`+k?f2h5mv;mM4gK>M6!-uE1hnA~P_?8O+wWh(`!4wX{Cn2j=z=is`~Uxb zzx=@K_DcEUJ7IZAUZAu8{sn~+Kmai^Fsw$4O9qB73=GeJhA}V*Ffg!yW&gnt6F`6g Y0QOrYft$MNbN~PV07*qoM6N<$f;FEW z@b~ZkKS1)&|37~i{`~p>`}cn&^2?@800G1T)Nta$zvt>t<757@uK4@^{4bCmpb7~3 z1tfp{|Md&VW|Wov$G`v(Kp+kO{{26+>+jbuf7A2+upj>Wf7$Q%RxoV1$N0e}Fas1Q1BW)@@rKJa|xATBWA`D>(WW1JFHv zzy7cP0k+{MTm!^O009K@!>LoJmn~avX#S_9;5YZ-KmTX``u`YaHjD&?*dJiPF#rS* zNW;&cKP?=87yABYZ~OCq-%n(9P{tpi22h9t6$1niNQ1e-pD1xDrvBdy@BT2zfI@>2 zY$OAO1fsuxAqeOsfB<52Wnfst00RHO2+qJn5C9Nh04p0wT74^6IRF3v07*qoM6N<$ Ef~oTCkN^Mx literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/tm.png b/base/resources.pk3dir/gfx/flags16/tm.png new file mode 100755 index 0000000000000000000000000000000000000000..828020ecd0f6fc73348373c9e7a235fdced09de7 GIT binary patch literal 593 zcmV-X0VKiqu&g@GZ_kb&V31Gky(*8`UselaloV1SZ886W^4001!n&i@1e004Y* zk0R&!|NaLC5DIk$@CyeC@AU9ebDYiJ)zswL{Qdm<{`>p<{rmm%TMiuO{1voVt6d+$)WVk%^O){nwx0zkdJv^%rQ#Z=eQ%0Ac}Z`19}Y zkI%oqe*ekA`2WvehFzDBOo*xZ{rB(cQ`_&qdGhP`Z=jyvAOx}jAb?nae){+CFDvWc zZ(siLa{c@D=g;LQw^HX+sY@u`d-M3!$G1SGAWQ!Ifj9{ufLMTG0<_`#=U?|Ye)D|< z8pH7G?=PVA*@stt1I-4xpA0e#40jk9 f${7d%fB*vk3(!F(w2U8u00000NkvXXu0mjf+94t7 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/tn.png b/base/resources.pk3dir/gfx/flags16/tn.png new file mode 100755 index 0000000000000000000000000000000000000000..183cdd3dc98c6957bde83f375a431e543a3ce9e4 GIT binary patch literal 495 zcmV@|4`Xj5kLT%gT|L_r@28Q3iff@h;hzaCwplYy<4FCT9KXmB7 zhQ|Nt)Bg(#gN*m^{Qvt8$Of<_K(zn?!~}BDpT8hi0uj&>pxItt|NHv>A2{&e(C|Mm zFGw7s;m;qS=>P!)((wQ9AF!W(0sZ}7M&|#9_5TYB{zpfHZ20g2t^wjCfB*tH2_nSs z8?4R7=Kq6S{f9wP5^T(0hI#XVIvK%6GC)WrB}fdh6SO{nUiXv3iAlW}aH!uJM5J&?vILH{_iZHeP0c!XQ3PuJ7 zfB*t%VEX-sK~fTI%wL8-Af1e0BN-qh5dHlNK|sX-0mS$fH6j^sMDRaYQUC}r0RA0L U-~OCsp8x;=07*qoM6N<$f)6&Rz5oCK literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/tr.png b/base/resources.pk3dir/gfx/flags16/tr.png new file mode 100755 index 0000000000000000000000000000000000000000..be32f77e9910c0896c1ee8e7ed4f0edf815a517e GIT binary patch literal 492 zcmV@|4`Xj5kLT%yy% zCxE~j7#aURc>+`lQtjr(@bBOM9XtMi`UFz<>-YcPzyAOF1!ObI$^vZw2q2J#|6qeb zs-vSBOie-Rl$HN?bb!_U0_g#3VEFwTr~x2=m_Y6Zss`GqsL0^t^nd#F|4B*zH*EO- z_3QuT%m4H6g6)A?0#pkSKujPf{rCwIb#eU5`( z{s2t}2q2J#|9}60{Pg58FvR|AYlEDjruP5RC6KEgJ^H_IA4CJhNdN)F0>q49OBog~ z{?Etvzo-c07$As@{Qu?4|3!FoS~(Xu$ujuK&Ki|5;f$7pYF;Nfxh(xqFs zZUMDjzjMbfEbRY>5C0Dx`v3aP|JSeozj_5kj66I)?%V+g05Jg0{{w&k0RJ5w0P^!X zSy|WJ-R9=z(aMV97z{4myy=pj4$^bx3|zy{hYtY)h`Ao9!QA5iyLbPuTmkB_PfP?Vee~$j z!-o&gUAyj)n+wu&>J&%=KmU)%j{yP*q=CWA45Z=rFNTYkfO?!$Q_o+&{s0WlT)E;? zRQUhj|NkdWF!J+%fBF<4fS7B68jOwqzkLe|6QI@S&;S4b-#s()-1Y1C!Qjl5tA6F> zpisYc>&x@!00G2Y!@$5~Xb92(47=Z8{{bD%z~Ggi4>bPny?b}>+&OjWQc!g@0~6Et z-Maw-h`Ac5K~JB7o9jOp7XvpB0}lu>-nqlT$mpA&|LpDCZ{NOs`t<42?c44-IbZwx z0Rjj;B7x{N1H(%OhUW|nPgz+XA3Vr_1a9x%4G>@ep<^{rq?UTJ00000NkvXXu0mjf Doa;3l literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/tv.png b/base/resources.pk3dir/gfx/flags16/tv.png new file mode 100755 index 0000000000000000000000000000000000000000..28274c5fb40e5d3bacd7c05d9a1b8017eeaffa6c GIT binary patch literal 536 zcmV+z0_XjSP)mzpv3Mmw05Sgm{~xFtLc$sUu>nR##!sI<0R#{WMEdpj-yJ7j ze)|0V&%b{_!~X#7`1>EofS_N0|E)GoUH&SsFy}2m05O4F@}ffYb$qvjbfSUipMQUU zgY^9U_4m&&5D8KZ)HC5u^uad<48Q&W1P~L@hOIAb7eDp_T4W)^*Xg48{r4ZBJ-_}k z{QCPJq~Q-pPnz693xQJ%zkUG(5aZwHtqd&u|9`*u&+TyOvq{_Ghd=&6oB?#w{~Yv(xYPgr|NRH*haKioowt*& z{dC`3v>70P7=Ql!$;`|Q@(GT>fdHT^FqGcDeG3pkjNS|k>E&sEfzAeo{ckY&=g(gd z`CCrwmxA8!XLtTy-uM6CzrVnM%iVPzAb=R%ks=j>et^j`MFs;Wh8c4i)_^1XKP)u> a1Q-A&>r+tW$-Nl>0000<~s!0-E7R}a|Ns2?4|9|}gs%Dgx1=;`*KrBFO{{8#+``2Fv2B6@-@8AFY{`(K80jdYk13&NH4;SYnOGgJvc0I@K9VW@Vk1}Xmk4~YK$|NH0P z-@pI<0D+Rop8&DnA}oIvEc_iD{O9-Y-=|4+U?1uFgf@9*z_zyJRJ z%fS3QR^zuR^Y0tyerNXndi(YlP_?gzto2+5fB<3vIsj-gQ0X6_*?&Q*d^>boB3^zoi8Kq^tbl{qlR!{9jwQ|Nij< z=(=A?F~8j-MSe1{Hl8Yc@zaXo%Ljk}VgUvb(2HJbe?0kqy?_3vsPXrUmq2rWE6M!I zE@4*I;Mw}vw&7&iFGdC>zW)rr{s9CK3xfnhrsi*1wqMhx{@J=6sPgxpU%z6)f4fBr zzxpd#a3tyYE8}0lKnA+|-+zWbe*glA<)R0}-=}{Pnt#7~1q_Mb;=;f3i~oshNgsS> zIr~z~(_bRL|NZ|1LO_>;A_pLVSoBpHQd9nLa7ao@{lMMx#__lBLe9Cjx?EiU z71{s)`Oon8FXP|;z>s7BItd_v7-5mj(Adb}701wVj$!S*>kNN{fN~5FV)t0eYh-DxnQ(+0I@JIfmA>F`X8wD?>`2h#NWRRzyE`zA&Pzh5tt#% z!^rUCA3y+sZ1@LM1hf`pHc0ia|NsB|1uKPX0CRu;1-SztfLMSo`wOxir1}rsY$VlC z667idh7Sw?0mQ-}a!Q0#;n&}vAb0=!_Zy@WNd5!6=O2ju7s{65Vq=gx0uVrqe;+b1 z$mIY3|KLBvF9x7j{{!v#g_UGtQhI;<6hHv607H@yECdWlR7EJN!LomVp$!l~APvkQ z4p0cL2#YobhQA>6hXEjfKpL3-19eKmL_s!=;22W8vpXP)6RGKQPvx1q)UK1Q6rb{|u}Q zRsa7#{m<~1f#L7}|GzNK{&HxZVEKJ4>jAefr9{u_M=MTegAo-i2ynN}MJ5kZm z42KRel$J95{>|{~*Z<$Y8RdVo9Ap3pAeIsa2H!t_KmPs=bot-kKnMR0GBy2s>sC=w zQFmwO;@`jj{`v(%zkl=p`BTQg01!Yd{Xp;j{qx|@pI^U!0X_En_iwRd$6{h)tX8f( zaOhC?&!0e%U%!3phy1#1%V=eK#YHXK~n$!{#(ib5I~Gyfqpu4^P)1J@ZrOUii!$=0Ad7ci1(2A^!3kwFaT->5i7Ttz54h6XL$JkA3s3o z=g)t?e>01U3h&zo5I`(I-#Hr#t~u}$WXZu-Kyv1Rm&rE5wcB1YFI@@=0EYkn8G$4- z^Xb{M0Ro8S57@^*QJ}#<$Im$M^4iKw z00a=@`Sa(sw6y;I{R{T)e~6KA2AmBHF`#D(ii!XNh(#nN}rF)(}plRy9vU;su%e@J`J?dSji002ov JPDHLkV1n4Y8}|SJ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/us.png b/base/resources.pk3dir/gfx/flags16/us.png new file mode 100755 index 0000000000000000000000000000000000000000..10f451fe85c41c6c9a06d543a57114ae2f87ecc1 GIT binary patch literal 609 zcmV-n0-pVeP){qW|y?pud`Sa)3|NY&vWd%S0u>b>P!2!lUe;6EF*#G_c zFVXVt@6Q{uX@40W{p0iY2Aa+A^Cu7i8KT+YH}2j52q4BskM2rJ$^k9;2Xxc_|Np=M z&VaLlA*IO5FlECMfB<5VUNC{tBZO(|zW*;@GJN;|bTJ71`0*d;`d`2P!x=ymOA`2> z+y@9C##^^8%gd{MW@Y91_2d742B2~OQNf=-zkmD?Vqkdk_wPTUNeuu2#KPTG{_;O4 v7C%8E5*DLB7#Kb?Fnj}}-(W6879hX?8lYRg`Y`<~00000NkvXXu0mjfD6Jtx literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/uy.png b/base/resources.pk3dir/gfx/flags16/uy.png new file mode 100755 index 0000000000000000000000000000000000000000..31d948a067fe02d067a8c2e69f28cca446bc7c57 GIT binary patch literal 532 zcmV+v0_**WP)_vmzq~N}&z08z z0*LYY{pZr+B0$d}2MCnI@DC;m3N;oM#uMkR0R#{ugY)L9Y<*xj0QCR^`!^)W!R$Za z5CobHbl5+T3;%B|S`QFFjQ1Zt|MTw;G#Vi+hCg5i(ELAtfD|ak8UBG;ObiSF0R{lf Wla#5zB1?M!0000JMe1P}`Y1HZufM;3|NZsr4^XwNEI-g5fB<4iWtjhPj`qjL zFGT_P{{Q>;-(R370Ro7T!5$Ws$Po%5A+Zb!3j_cNFaSC{Z(fWD@s$7o002ovPDHLk FV1jsy^u+)G literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/va.png b/base/resources.pk3dir/gfx/flags16/va.png new file mode 100755 index 0000000000000000000000000000000000000000..b31eaf225d6fd770e0557c2baf8747c91ce88983 GIT binary patch literal 553 zcmV+^0@nSBP)|05Jg_ z#sD@3Z1&&(|Ni{{_Zx)%v%Gr!NnLzkb;C z@#QWhJ{xI9$+*)bNX$S?E90e{K^EMkYok78VXhR-hjM0*K`g z$j^Tmm_>oEVgxdn{xJOg$-v0L$jHRN$OsH@P9Y&+^ne@=1^@xXcy~X;zaPM$WdOPj ri2i^{AeYDB@IM9-1r;P))4B5XW#s0WPsWLbObPT z00IbN14#96puqp%TKvBf)PA*{`~CO-uM~~n%6z|m{re4Z55!3T0R+GV5`UO(`=kK4te?c|?1P~}#f$jmC10=!0@{8gBFK@Zu z-~WJALqveC|MTzfA7GIDVE_mqkOrW8BqZ2?K4D^#WMJTBVE7%b47BbKBg1c?EHl#| zW&XdQF#ikE01!Zo3=CVrargu%_x5NZPzVyc@Ms2-@*Gr#1lu5DU{kh6%sopXB}uDxAo`@Bt_a*7F+) z{Q{%kjEu5C8vp``Wse8Lf5q7h438n|z~nEOsZga5l7ZnjPy;{!05Jg0{{a91!FF~d z;^O)I`~dv>{`>s@o}L{E2?GEB|Mm6!N=n`P`~Ld+{`>p?A0G$7!M*~B3FM_eAU;q6 zNCH*w+4I@c^Ny?Q?QPpWZQiU1R1HBuWkA0H1P}`l|NYDG=gP=Ihyj(0CItil0R{kn^jdV2 S*Eqib00003_-&c2+@O*Bba;fM%rBo$$qwJnuekcf#0k*RG7MM`2+5Y7dK4k?R% z*@ue~6f;u_A~T0evP6qS=VxXnGS_mt>CSmS&gmG`kLSL)e_Vf_=c&!fKB7`4C;*C(7s2O*P zOs1$U0urzb3<=a`d9ABG4Q$eK<6~5Cg~V%B8`UqrfRSN8f&?QTVICs^VT=&p*?Eut zt4Ur&-BL_ON(Z|Xfgo93lf|gRkT$Mz-7^OQoD^XMF@}g>R?uoU0094KbXv)l?aF0E zh@GXQVr04m@05R(Rjxq*p|CCIRfv;QJmH1kf!hsqX*sha?_l;f%e5i5I~4YG#H4;6sPG2&U~bv( zNr`eMXGIX9?wP^zPQP(6+&$05Jg0{{;N}{t6CR|M}we`P%>f+X)5&j)Fc04NUj< zI`HZ2Woe@k6UF22`V|Qe2MTi(6bb?WF#yj00*Hv<{QLmnFd+P z9@fS%;@9^E|H1b5`Vk8^2@Yw;#}(}C_yUN9iGkt%y>Cxm>T2lO13mifZBc!n`jhHL z!MK>$6Z_d%|GfHMapIVnqod%T-`{|q1_&S~IR%b4Z+;63vi@iI?>jBz=eJjkjQ{>J z{QUQa@gMhBW_GSe5B=V~`@+h~@c%z3lmG&V@$K8U{QUg?|NjRX|KX9x@@rf{MxIY^ z?fG>3gQ&3ruaE-Yw>fW_PfAH~0~Or8dmA8tSRg?T(ZDLQOiOw%6RWM9%$i>kkAMHu z-oH0qLBYb*loP0ck&zJ?LI42-(g0BnBsn<*tTlsx%zxbLe*S!R<%*E3>|Z7(9Y#iG zpdch>0Ro8e`Sa&!arp;m4%k`<1H=Xjf<=G;Aix0Vb{`Xo7A9K&0000@|4`Xj5kLT%B_22*h{r-RE_y1qN|Ns8=|JN^|IHRmA&<212VgZ}|A4N4# z+WpUe-rxU^{Q|504bi~x`!`SnKmf4-F(Xhl(8fQ1fG+vp^85d{-~aW0|NsB{f9tRR zg1`PJA~XO^2M8drlm7gLxRT-bpa1p0|1bLmQVm3Azy5pw{{IQ;B%q-{(*XjA3FM@| zf53hMJK)W)|CK-uK=ku}!>|93eu7kk5yVLV0R(o^Z;+)RSAk6exg_KF|98LtFaPy_ z#c#OrKtum9FaQJ)NCPuC$bbfbRI>n`@$3IHusZAC|2cmD|MKhqAD{+Mr~sV<5I`Ue zOuzpyNJ@f@0s0=KlTj9AB*>SXe;D}wK*A7+fQkVEi190GMB<5K2mlB$03I1qT8uIj Q5C8xG07*qoM6N<$f}XY6qW}N^ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/vu.png b/base/resources.pk3dir/gfx/flags16/vu.png new file mode 100755 index 0000000000000000000000000000000000000000..b3397bc63d718b344e604266259134e653925c9d GIT binary patch literal 604 zcmV-i0;BzjP)7(YpZ_rO%ce~L0mQ<@*ghnz= zZvXM=_iyVze?clB=ogUu_5ar|Ae&KE_8$WSKmaiTHT?Vg|MaE5OE>+VAUAUr;?j4FCZIvLVX%uQ>mocOU*NTK^}%njy93_oP3+fBpUa=kKpye|`ZO zzyE?r`Mc+5Xcyo_v6>E-#|Nl{r(LkAS94bRQz)6 z1Oq?-fi&zp{`>yDUnV+0)eJF{zWfaN_0t9DjNiZhfxY|}ME?2z=O_CghC>Vh0R+AWw znBTkss=gWN$ME*Y`(NAt{QjkN;J}02MB(&;Kdc-80mKB<@b~YZKMV}g5wYSaSzrGC z<#lj=zkTD+H$ND}dANT6R9Lq3!_gzJFJEF25d}I4Ab>y`n3$OVE?Nk3?w(!me*OA# z|pNg&$Q z5()=&no#y6=Krof_F9Achf)A{nF9v;`|P8;$Q9J(&$2e@kA>cu?oN0tdr?p!r`I00M}SAs-l}3=F@( m=nn?tAB_7COfoP41Q-C;+8YpPdg;0V0000`!~0W%8&aG{{H+4 zRPp!M??1nPG5q=k)Wabw3seITKp+kO{xLwc{r>&$?_UrCGJgGL;^k4Qujka#`tk7L zjnovNAkb9+0R(gvNCCu>f4~1QF);xde}DY=^Xr#I=|`5hhp|NZyp>({@(egUPqbabS$v+tIbNu;L>xVSv%=>ggR z5I`*V_U`A@(fj`3!N1?XfHr^}17rYw{OcFcC69Z0BvMmfELgy8V88%&5l9HrLN(5b9xs8l&q^Gm-@&XkD1Q1BW|346ee?wJ+H2_`p`^l3V z+1Wtu|3AMO{`_T8Q2{Cj2q2bUARGR$NlJo(=nv2bFrDDw2U!bb{QV0-KNuJQ0*G-b s1H(6@xcrC2{sj~H2V-zBFaQJ?0G2^Lae{Q+uK)l507*qoM6N<$f;6K8u>b%7 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/ws.png b/base/resources.pk3dir/gfx/flags16/ws.png new file mode 100755 index 0000000000000000000000000000000000000000..c16950802ea95b40a4e024be6cce870b1991f40e GIT binary patch literal 476 zcmV<20VDp2P)>E69JA<-5ee*C|6>(%ey48MQ<`3*E1sOaY}WDP*a00a=wNxxYB{9yb2 zOU?HFZD2h;3gJl2w`NO~f5I`Ue%-|qnfGfh(_6MlpFT>xzKtBKk z5J&^l?>`KZl3-*0GW-GQWCR<@03m_s?_UT4Dh3E3#;>Rm$$$~H$WlN65MTgr(_Ikn S3@&c~00004%P)h=Z!r1m*T3JtfNUmdS)dI70mLHE z+xy?%p5eHez0mS(A>sL-rPOy{yGk_s3 zz{tq>=+Ps90Al&~?;k`pNCN|I|RMxbJV00L=%3E(v!XamT}{{RArWx|9$7Z{pWi2U{IKN}lRCnF;x&=P&!(V3Rv&T;|GP6K500a;d#1A^U zy8js%fB*jT=jRXRU*A|5K#2L*r(ZvQ{P_O!=da%umKG4l0|XG%NkAKznV4BvSbj4y zawHV~fBoj~uiyXJSQwZYIoR0QIXM3O{tc7`Dgy{0# literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/za.png b/base/resources.pk3dir/gfx/flags16/za.png new file mode 100755 index 0000000000000000000000000000000000000000..57c58e2119f402072640ca758657798b621f3fb1 GIT binary patch literal 642 zcmV-|0)737P)Cfuwe;F7c=r;qyPX>nX3=Cfx7(O#Fd}LsF&%p4OfdL?Z7#j~W z{9>KL@b8bfkaUokt?1q(EJu$q{Qdp^&mV?AfBydlG2rBvO`8A$h{fmzgIW0J+B07s zK74uV#pQB`MAdI!SdN|k|KJ`--LK#OfB*Xb>lcvCC@cGqfdL=@05Jg0{{a910Lj6A zAt&mC*9zzO1pWQ@b1`Tn1`iV6=KuBe|Nj2}{{8>`{{Q~|0SOB6tE&PCq@k>=Oh@B| zgDu0v2b@p;u)h2C^Y4EK4rY$O|Ni{`3qc?^$?%A8m^2X}fLMSU{`~p7aqHLD@0rW| zzIWc|c>Ry-$DePXKfn0(_xG>AzksTL{re5n#{Tyw!wUw000L?F`}dEV6O*(3zu6Di z9{gne@#pKG|NpqSh1vf81DXBz&mW+Me}8zmL>PD&00Ic4!QY)xLzl7RCikV!EWdtz zoorLj&BXoYF88-DfB*gk`{Eza7yo#;S!C4G00M|*elvr*8B6X-zBgb0FtGkEHc8mM zoOScs_b*;Q0~!ksq<=swfJjA!^Ww!_00G4E&x@hvA~zQkvxU59n3VsHd7Nj?ec|R~ zkmuqAx#JHo0{#K*`TG}00$uYDAb=PdGJ(Ek5Vx?d6PS=4{E7kSFNS|$^b5xL14ayB ck_{lh0N_F{UmK66LjV8(07*qoM6N<$f>aVd=Kufz literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/flags16/zm.png b/base/resources.pk3dir/gfx/flags16/zm.png new file mode 100755 index 0000000000000000000000000000000000000000..c25b07beef894408ae11c3be294d6e0eeb28c0bb GIT binary patch literal 500 zcmVLz(k0+Rp#|Nr~{@4x^5fB>iy$Oe)U zA3pkg`SAPSuU~)vaR2(F*|!oPfLI`Azxw(Lr25~#KmY#x{rl(7|GyyW-|wp|{||Bf z=)Cuc_0O*fYWnY`7ytr@1!(pEfB(To0uBE22c#NA{{8#+_rKq)zyAFG`zKdY6euFW z2yzlY0I`6SGJqWbGV%`;{r&ytA5hcp-u`P`AAdOg`t|1D?}h2=^+y>10tjRS&?yMj zfBygt2HEouXg1LCzyJLD1w#LR1MLR}1V8|>0KE@nffPa916Bvu_V4#Epof105yNkw zzknJ50tl=DS->P)FK#X6%e&u3i|I74$@9uP0*YE!se={)r{r~?r68Z&3 zzZn^2KYiK`5I`&p3=IF7JHD>uaSofgtUAf*-w!6nU;qF7`S<(x|35&+uYZ4j|Njjl zS;T)|pU40ZKrEjoRWbQ1@P?oGFzcPCjLiCzcU8ZC{rmejNW<@6e}U*1kPT$~=Kk_~ z83O}A05QHjx|ikdd7h}_|NsB_wl9j+&d<}^`}fbEzkmP!1q4tEL@O#P9zA*#Ab?m{ zv`qe9Isj6Ah@Z*IdsTw}WYHgB8-D!*lmGvK*?)d>i2vThzyJ_HEdLn(@uk-N0|t-& z`$Yv&?#y3UfPVP*`ya#a|BS!>G5-DsFR)1c1&eHCHYDzO7ytqc0P0;>l>h9)WB>pF M07*qoM6N<$g71PE`~Uy| literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/CREDITS b/base/resources.pk3dir/gfx/icon16/CREDITS new file mode 100644 index 00000000..cd3339f9 --- /dev/null +++ b/base/resources.pk3dir/gfx/icon16/CREDITS @@ -0,0 +1,3 @@ +Silk Icons by Mark James +https://github.com/markjames/famfamfam-silk-icons +http://www.famfamfam.com/lab/icons/silk/ diff --git a/base/resources.pk3dir/gfx/icon16/accept.png b/base/resources.pk3dir/gfx/icon16/accept.png new file mode 100644 index 0000000000000000000000000000000000000000..89c8129a490b329f3165f32fa0781701aab417ea GIT binary patch literal 781 zcmV+o1M>WdP)4-QibtN)VXQDpczE`xXAkUjh%RI>;okxb7K@0kpyQ1k_Y(|Oe7$m(^ zNYX>mI||sUbmn+c3<&FnE=4u#()KBS^SH8e)Qs5i!#lY=$-1gbH6VluzU=m=EP78&5vQ z-?+fFP-G2l&l_QzYealK$;1Rl?FkzXR&Jv@fBPNjCr#AYRyJ7UJQ0v#?)7Ott=>3`#-pV!7>9}>Q1jL)H6h&gkP@3nI=+F3nA~M>u#(n* z8T!#8oEw&-mED4!h4s!N@Jo3S7N&Q6%6l3}nlcd~X@>;uelvPsSkXIgg~e+^T1zSf z3SNj(5%jK~i8@b;C9VHk(~TedF+gQSL8D5xnVSSWAVY>J9b+m>@{iq7_KE}go~11+5s4;8hc+i0Xa zI1j@EX5!S+Me6HNqKzU5YQwL;-W5$p%ZMKMeR<%zp69-~?<4?8|C8S?bklXr4v&Ov zb&06v2|-x?qB`90yn>Qi%Sh2^G4n)$ZdyvTPf9}1)_buUT7>`e2G&2VU@~Bb(o+Mz zi4)>IxlSY${Dj4k={-9RzU^W5g9|2V5RZ2ZulL9s2xQbZ@r6eP9Ra5u(s|C0Nj#&4>wTSkb?%#=9?@ z^oxDy-O@tyN{L@by(WWvQ3%CyEu8x{+#Jb4-h&K9Owi)2pgg+heWDyked|3R$$kL@A z#sp1v-r+=G4B8D6DqsDH0@7OztA7aT9qc1Py{()w`m``?Y0&gi2=ROcc-9+nU^I6< zT=e_Y=vSnG@?3Ue{BW5ONFttcE!R-R_W4O01|0-|K-YNXLo2`4Qv z`r1LxR6#yf3FB%T95gJnaKKivA~Z}S9A(ZxEDK}O3T04USJ P00000NkvXXu0mjf^IS-S literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/anchor.png b/base/resources.pk3dir/gfx/icon16/anchor.png new file mode 100644 index 0000000000000000000000000000000000000000..9b3422c61e5d23434d085834b82eed7a7363976e GIT binary patch literal 523 zcmV+m0`&cfP)JNR5;6} zQ!#78Koq{K0R;zL3K^ueKcPdX4$`e#^8*A?$4(UrP73NEC=L?Wb`e}#+M#4AI28&O z(h7D{iBLo^6ibLnntoS;4W+RSeem(_-M#O-mv=AJwr%ns(1oktvOHk&-Wjo2=gN^Bj3SRR*}a0NpG5_ zolK`M<47b@MJ$6*<9VLqM#|QJ9FOl*`~9c!VzJ0#yuW&YL-uTJXs#7SsfEK~0YXX4 z0b#F1DNRn42?6;6#8Y4fXr9klsZ0WbcEP)8e6`gpm!y1M!N^ZV(=IC*t) z{^;nqJv-tM$9J1L2QJ2DN!#51=1_l@G`2=6e0lehL%sic%`_4--LFM}IF!KzJCseW zq1I3__Z40|e?qyK1__gzP(qrBf-G7SQbQ`#Lw94WVe(o`qg+f4hy;Qju)q#I(9{`% zQmAGomzhQ!b|gq>KqL@IkO~$=Koi}a$u6d07kiS}NoYVMJjAeZpaB*;wwcDdEbK@K zNP;B7RzhQ|H9AlUO<`J>m1(5R)Pb-iLBb@7Jp)}LHdAb-VVgYxVoTzGoqu{~a>6uj zeqCRFI9pC#h09bGwy9;oHcp6(RB%jeY^F=Ll!S+9JkVe4nDG7tJMQiP00000Ag3?`k8$#1J0F}NdayEtTz+~+#EG995YAF(1xew#=1J)ogJuY z3Lxu(1VP;KAh`GKm^?X0f~UCV*)Nf5F(3GKr=#9qzp;L29U)FF98>T4&VoHZ|-ho>^FRq4ws;uOVa=V002ovPDHLk FV1kR43LgLf literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/application_cascade.png b/base/resources.pk3dir/gfx/icon16/application_cascade.png new file mode 100644 index 0000000000000000000000000000000000000000..da5c622eaca0deb4866135926af1d2aa5101d106 GIT binary patch literal 524 zcmV+n0`vWeP)}lwk9A2Ze|&iZoIgAZ3MTi0rviU@eS5?r z4KA#JuLrmglUjU7y&F^VIw}$Rg3uR)V-k9U&=-WhAoK;n1)+F@6(FfbKq!_YoYN6- z@oomdg%KbsI|VMR`^0v};X*@SkkbJdKbzvy#h(jwfiBRE_p0E=F98r%Yr~OBPWzsj6v!X?6(f7#B3EJn O0000hj32+Ia2PFSwHp_;8^u8>r6{e*krHy43#H^jT&z}Wa&xpokqZtA zFR&Fehhe_gp*x{i&XLj%HzdqAeQvxDT1Rjn;gaWw} z5^~2QShuR2o0yn9fA7Y?Xzt(DKhn`?rmhAn(VT1h2r!!4rBZw52P-vSDzPZb#g$`y ztkj8XEoxZ`Y73PkKp{LJ5D~&7@Je_kT)~2i-c6l&IJJyK&5~gfN`_2W7%3TM2{XqE zQA8qFq861?%N|ZG0Wt%FLJ$TKq7Wo2$Odl0Q&0;JYFQzcn1MtBWCjLiAQxdE1Cmih zK`p|mAf*(48Y1z>=gVSoY2jATaZ?l66O4$*k`47+`l zweRoK+p__ghH^x(%m8DN8Gl-sYSGx#3kS}zEMMMC5wqj&noaWd37uvw=_X01NGD-Z+i^1;8t2&z(w`{C(PM?|mR`Ky`;pI zld+0ZK^TRQ&AxX;a%I->Ls?9Vv(;_9E)=9HE>13WHNsnHAS>LKQkMbVH_QE8X!1!(q^p{6+N_ X4^=JUQP|Z100000NkvXXu0mjfgEH)N literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/application_edit.png b/base/resources.pk3dir/gfx/icon16/application_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..fb2efb8775442af862ef0ef111f371e5857928d3 GIT binary patch literal 703 zcmV;w0zmzVP)FxeKF=OosmQ6jmTLP{}-6iF>nO8f(+aY2!Xm^*5Av6NhR zD0!Nar%`rnu~v@R4hO^8&iS41=VQN>+65QO>m_E!|B#IbuI^pAy5?9WYjHC`6;s8j z!_-hy%sJEya}KAD$C|Z-~!ZLFQctG09Uhp@QPcl?mU}7$E{?cz}t3fC%LK?;}5+keI!OTyHb6 z@j}nbBm-HHT&CJnb^IYBAVSCka_RdNzT74;XDve?FCx*eM2ky^TZSvCN4lf#zADBt{VLMZ58~8Xlk&tIj2}J+_M1=n24SuBB zC|kIW{HG=&F(WrHgY=^pRBSp=QTYN)m5{Hh{2@SBTQi04uPMk>dS9PrQdx|l%yhmz zOH#Sz0@1`YLTX0HPj&aS)SnFM)H&2CwbI1q`b)fRK1k<-HpW#}^Sv*{jiIgdH9W>t zQ6<#EFflVmJF;g{aA;S(kLP%K=NdiTT|X03N>|n%ZExo<#LO72ZdK{vlG)|{vIVoS lXs&IrKfQB()Zh|+zd6v%`rDz z6?4Z`Q8OB=D}|}4g>&PV`$y8ABR#`axw_DjV?F8$MI8o4(qhF!@oS#-Dpfr2Tk7gu z9B5~~P7lozrS3*l&J+jS95pZ;Ge^zP%+btIH_Ga?wKkxpL;-gq2|^GEK?n&XBBUXZ zCMo{&1?6``R7r{2s+7nwB?@Xv6aW!Hf{+9uB!UD8USfG}ociW{R6gA&tqw${Miktf zRU$+I2qJ_aB#BV`@POLpE*iIXQJ8xO`57WJB?@NB8W8~zq5x=qfp72b(XhD*{c(pa zou~Nz_6BYlW=0gUN`+M-hzOC05Pf-bljip0usq4cwd>S3mH099i0`wH$toF9a5bU? z5I{r_pzwJTEiBQnsfex2fE${BN?Y$)=AT@lie;i;W~>n)0OHExv#T`i+K&}q;Z~x% zuLCQ8B$u0}amOLLY9@%}#NgOi%g$~6ri!Vds_fbDl#>T@wC=7!^Aot2d479}?!HbW z*$6eqcr`C*eJwEdkCSfuyE`#n&&HzI*;w%0FZ)<=o_G qU&+mJGu#X}!_9Fs+#Jks_tsxXE+vBxy0Iew0000u4Z literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/application_form.png b/base/resources.pk3dir/gfx/icon16/application_form.png new file mode 100644 index 0000000000000000000000000000000000000000..807b862cfc087b70dcdd971af3ac92688484e998 GIT binary patch literal 467 zcmV;^0WAKBP)4nWfMy23V#h*$3p-!?D%AI~T5+JJ;5Qi)|`;Y?)XOj2U`VS70o zp1%L~Y4f1;U-b7MEOk38OU$EtImvzCpiEkKCg)@3^{;h@nc_6NuOBn7?ZF9Ev4w3+ zWiSxI_v2&k@_b{1R8kdeGLx;rFK&F@c}mqZ4YwJO$7q^VC6&nL^Y#-6g9F*zM-oa= z70W0^1X#=%!t{DQE-wCJ^Pd1r08&yFDUlL$EtoM3e+;?Hv-Nc(QI%=il9}v$`OS^N z)(TbAG~DLw><`m+N>!Xf5_@kR0j83~eKLh5sv-%=fC#``TU}jaG#UW`VS>Ph2!jLJ zROR&N$x3B;J002ov JPDHLkV1im=zqk7R5;6} zlg(=rK^VsO-|*I>7Z08a{s)Rsf(J|SV_Rz!8yef7kVJ&ghD4GkA*3yaw3HgOrMaY5 zCEF^>3bs|O#wgl0$9$0`oBc>UmB*RcC2f(EL>GQM^S=AeGc)h*Z~(affwPP)k4&ZW zy8GEaTu%wfT{sti;{L*S+?&tAF_*=7d}1I*%E6Q~85vri^Z} zN8TMU1G@6RU=6$lGjJvM&}=rl=7#UJVc>l73ynqtIzxx9>ufBFVp|%dhW84l0cn`3 zs_37{w$MmS3)?-Krs10Bm0>`;T~`z+b%IhiRXNdszQ6MDg<(KHRjnpNmSv_4xkj`` za)urv8+pROgH^-8k@yNpl2A3FW2q|rb?$g7jPaSPu!j1;KROSKbIdTX&wfIsQaRQG z8XrBv^AAh#tPEl;H;pev0payKxEwx%-jP#5ZZx)yQmI5Jn`&^>U?^|_>2DFFe?(av z+_;JG#w}{_o3lkXQ79A%1r!N|7R8ocbf3k`T;f_-wuiF&l>i>!Ju~? z*C#Th%WJGr{q8i**?JHVhTs!;Hrbcq4|mYXjU$DVmx8A;B@DBbsnVGBpwnwhiv0wY eZrfBp&Hn+e<03_si;HOh0000Y=*2{WUucY-zdJL^dl3I%>;ad8o^ z7>UT-aEZGeIS2v;T;fmM9XBTt$%UH}0?1h*2qK@)Ge19v#5w^G0dO}Gk-On;h*g0V zg0c5w{A6?(dp$&D`V;BhwH(@f3^+wpiDS%+&U-Vg>20eaQ79BhObrh(SA506v+ZnZ z$g})zgzWPtJU(945y>2Pr{~-rKqTCq^~N9e(A;`~%*Utj>?T{b@1P-MscT0g(~ZNI{bH#Y_Utm11j?0+FF&hK-qRX-TePYY3~f zgtoM;)~2M+AJew!(sr+7^KN&$cgxoJcJAGZGzzQ(AD(j#=leYm&p8hTfchUO*=18r zr!~koJq|$qh+zB()q@3G>7PU6y;(H$c~Nhe#3lU)C~l9VR_BJ=;N(S}WT3GGbJ~$L zY!^k>SWYq!Z~hmmJ4PWHsEvN4)9Gy^Z?)wOR0E3;1OdDR51!|xxx?Z3jR~6$3lGcS zw`wrecMQ|rMHQ4-uw*icvKH@8Qe-U(ejNgB1!Gqt;e8II!iaktI@}570bpEkH@7b5obwc$sUX75)sc{ zLoV$^I#`Q!&qeqKv2}x;Q6ZOcK?qbLvr>-a zyc(hY)2O@Nn=hiGX9AH(WK#{q_3OcQFyqRCxB{6^XTi-jVaae3jL(UZMoZqHPUiu` zFod;2WZ-*e#Qe)flJ*;9mgV@eat;ZSNkD%BUpZPjbEd(ZH>lOVM>tFq!k`K6p&rZ) zt12-&(V<8oA9F-Oc!oCq@PvQW{0``D3AONE*fZt6-G6K6?>+q?gw;DtTL1t607*qoM6N<$g3ymi=>Px# literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/application_form_magnify.png b/base/resources.pk3dir/gfx/icon16/application_form_magnify.png new file mode 100644 index 0000000000000000000000000000000000000000..7b7fbd17e39353723122664abae8461f3788227d GIT binary patch literal 612 zcmV-q0-ODbP)PDrjnPX=rH; zqQ${l4iyS4Fv&4giDwVmm?Q$ zhTL&8OyXERuCJ_Y++wrjMj8GD99k(+b> z<{<5wp8G;7au@E7lX7q%1U@V;^Dm<#Bbba-gga)&*~B}OVT z8FJ_8^ce^a9*{dnoOjg?w)UFTS_KNZh~pjN>QDihNJTD3CPDxgha7@4JUq?D&XIEY9KSYW_M1j`N1m2BQ6{jt9pgXOIG5 z7fYv3PRIVYk-8wpOV0eq;C3`{e8D((T~xwBz-I8+ZE$ y`XBWUUFlg}deaE*PP<-CUAQ$+zVt#$I(`F{%rIviW}jLB00009TL{7iX$V@PAta(9$|8b7D6wp-IURZdO^p#W zhGj%3h}IwkopYY&+|PAgc}vbAem;r__Cgn?7OtN?KmKI17sC;NJK>JG5gvFrVTMN# zW|%vN_vh}?(%S8}PbcQ9@iXId`-X{dTVVoMbkJeoYg zZe4x6LQzFH#h^6;2oKD`3ETs7$J)T!z`_|=FnatD=0;HwL7^lRK_n3h@B_uHVGm~Ku92vAS`gf?5Br# z8{9Z~kHXz3lDn}(5=ayYND`_NGav5KA9U$9znOkFMd9ugsm+;f5|St+frNR>{r5M? zxnXQ%jM1ZG)Va%*SCi!2P^2)Y=l}vFAwaUKcgHXPW0kkyS9ex(J9 zLu@IU7soQkH&cA1hmXWM zDZ#H?v3PJ5$Hq5OmbDN{wJ%9%wAR zT-Qu9!vIN`896F;t~rD&@Nfe0`Nv1rEgogE>hi36i1p_V%rE6ZqX5JdGmz-z3Rm#{ z+Z*c0z*?bg!mefM79{Zs`zK3~u)rkEuD#mHG}dlY@$@R6?<^o~D%1C9AK Udps;mZ~y=R07*qoM6N<$f`qvmMgRZ+ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/application_home.png b/base/resources.pk3dir/gfx/icon16/application_home.png new file mode 100644 index 0000000000000000000000000000000000000000..b60d0c85afc41d8888b874fb21fbb215a8678065 GIT binary patch literal 685 zcmV;e0#f~nP)I{hwZ<~aTagPdH^@uK zjY~?Dw;H9EMl7~jY&PfYJf}U+@AtF+YUNh@d;&9LB7zNj@9bW&y4W^QvDgey#Z(a$ zObs=~L{KwK1W{#5ln!@vbRT?hX7fc?Y${&J*Tmt>8vaK-T#*aFMOR5JtPGU-m&=A} z>TO{pOGy&t!=mG4xtM^3mKOte|UGJg?xP-rE$mV9Ba&%vrgIZ=IbKrquG}+;$3iho_m~IZ?q2fogS#R3qlEKgP5f zb4V+{nb+8a*%6*zK1`NoxG2O^Q9NgAj0pmk@4U(5NB5aEw}I1btqcwh5yvsj&CT4t zSL8s;X;8+f3SOuxj0=K*R0A{}A)k+EY-}V50x%;N*Wq#y<`|=@crHs*yjQ(1c>V1S zpUNF9?O#T1TuY%)U{Zb(?E`NqE$`v{vo;n^UCgH9MzS=+b0&&+^W}AtO2Rb}@>rRo0Q0^~dYKRD`il?SH=a@Wg zGEo%asTrQ@{?c`K*V%NlilCy12&#&tDXNN^VJesyYKp0%ig%Y$ftfK8Artf$>Q*=b T>SSUs00000NkvXXu0mjf_=`4z literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/application_key.png b/base/resources.pk3dir/gfx/icon16/application_key.png new file mode 100644 index 0000000000000000000000000000000000000000..998d65c6942453d764e0d5427e6a361cbdaca856 GIT binary patch literal 670 zcmV;P0%84$P)VY)5dRg+A)?a2)_PUQ=}3+N6D zvAM#+@`kM!V{-tZdE@rkmJI_g-<_cXFa;ngdkio&ynqp0w=gY5C?&SnjoM& zmLZk=!p^n}tjxWn(MBqDrqw?XSpzw#bPoa{5GYRc6RZqTzb8$8W`H2Mi*wCy7`V3k zOsG`{R2=|dh679l4TW;{JzHB(;tL}rw>7ZhztMPfA5xs}3CnT3=0E^5LqxE@KtZa3 zc=0nX$RaLJqAm+71(tu5g3x^B3ISA#L|9#Hl>J0*_#u*r(Q*-|Kf%>vam2^IDaOYa zu7s-kXN0N{VQKOOxzXorX+4NVgNR>ZY%rpxR3Z@J>HG=0dT;fHv(qz~&IfUadXIX= zdylHp+0@7W_G3iZ9>TDm;nyX4#||);*ozrNiA|a6zHD86?LYpuG{ZkEO_ z+;HhiElFxjo6yjHV871y>^#rs^RXwCT*&fzIWyybxb6!Br}uWWU;9$Bf*GKSsUj+v z8fuD(pk|l|qDo!0UmO{kxHx#D=eBF#)81E=FC^>ptVCh4Bz?ebSMrvWzAUg(nYV;x z&cwLV+rmnnxcZLBnJG~v2nK}tXOutoV-he?G$bx z+bC({FJWHT=iUt#X!bBen!k*-=p@PWvgC{e!HNhnW4l8{R)d>tR6uCaqq{zj!VO;W#; z=I-mb+9r}T#Z-x$suC48_VSB{1!iC0r8N1H^86&l9p|WTJgFy@`WU!f)*0Mw4O9TnqBr{Y-GHDVuib)O%q7o!E zKlFxCD=Me;C78Guop0xOj_&HYpW_Dm*t+3@`&{>Re&;#QbB+dp=6|HIxRxBDrUi@fE_t7hH*d!sYoQrtW@#bM76y@j{#K^yGu+Y%mKB@Gh?6AT=?YQ30NZKe^FU`jD8!o`SZhpef2|bb8oqiKx}PSX=Ml zPpyStYfYXXpH2?}Y{RJJ!2oi<&p};TK}S+S+g$})Z3*j525N|?ZghFxdh>+}pxvhG zGk`)6rXB-{4Ai03Fi?wD)KO4x$=GO0Jb&iKa}_{G#Q{4z9Iy-OF-d*(m3BeRA&BbK z^=B$Txc7MvKx%ipc$rQk6bd1cNFW#tVzpdGZF38^haSzwg)nqF-C@mC?4t@`l4KbR zED(uAP_0%`sZ@~5<@oh{JdRSS#JxhHz`fDY(Oa5JbMN<#=5;m;pU;Ql$_i!!0hrBZ z*ladLqfvM~9^R7|U^9XUg3!=7qi^>B;cyr;Gcz0@NfL}kBQlu`ip3)G`8-mo6!&OG z0KeZa(!a2D?#>(jWtk`Zu%CBwz)9;x96LS&gTVlc#ll5Bc_&U^-~hYbUf=g;9bv_m z_?>N1J()~yE-x=57K_24C(^PW7KQHHYn09vi~kY2ApYBHIAPfkv@9S(=c)EgTc jvoejazDXX-B1Y!m%PGQ6x$c z#f9@AK!Oh=jElv$CqBcNDKEr@t}K+jhk=(*)=6Nf9`DW>GPMDbI$#A zadnmXt6lDNZUb=D%3-T`<7 zxtL}GCkYVlWRqqF51NHf9Yl>2gOi8|vh54F$BDrs0>$iLAcx_0>Z+sNt2+U0SgfoD!Wm8sxbT>nyV*Byc6US+Mev^`pI%-cR#%pfrES|$2%tg@7${Im zLBJqCKm^~%kqyWahMtFC{m)BDn@^W+n<9Vs4o8^{xZi&Mv#JmPg~hDhyn9@iQaYl1 zb`JLD2V96U6l8WL=?n97fC_~~t>ED5npj0DEXy*Oju~q^dmy7QgiIy_{eJ&PQrd=O zTr3tLpD%!=R5+2n4HYIFZ-%8JGt|1(g~rh-D=YFj+Az zW(A5Kmc(%jan)&(SOLdLpDi*0KTl?3g3&8WuNWgH;XS@00@rm1q##!+l~R*`BVp_N zo+o>~-p$tT{t5Bs0?k82!-S(@;vSVo<7@Jfu3S^qP;(9ryrKIh{yWa!k>a)0QvY16 P00000NkvXXu0mjf=yc!b literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/application_put.png b/base/resources.pk3dir/gfx/icon16/application_put.png new file mode 100644 index 0000000000000000000000000000000000000000..c30cf59894473550b70d2ab97e2244af64c2ecd0 GIT binary patch literal 585 zcmV-P0=E5$P);No%bTEi-Lr>D_AI6iV#?A3~B^FfP%5GR1nd|DqtT_3=slpZLAdaE7%DZ zq7q}81xXPN76HNi^JdngC8_mhYI?w^U( z2gw6K?&>VvIx{ig&f_gAfExg@R2*<~)WC4e95q8rugZ<6&Z+ic)U*Onzk&oo-0>i| zIATHwf=EC_k<7^~keAhcD{H`r6aW_ify}`K%$&?2NJcK8;%KOhO|6b#^*;~+_kTbl z;Odxw3lN0NvI;PYFxpfMsWxLE%Z0^vw@I-i#zYz>Ufg_xS!EE)l=cip0Fkc0GbiElsF znK^ijVHt@UnK|0x!SlPMyan7K-~PV!>fW=oV5*oJs*0JRDPew=cw&P?(*;Eu5;d~( zYlq(NDUO%dUjxW~rt#|X#V_sY_PH1n-EQ~u$EWMFd)E6M=kt$dKcrzwpH{xkji3Jo X7}OeR*sz>k00000NkvXXu0mjfdXfo6 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/application_side_boxes.png b/base/resources.pk3dir/gfx/icon16/application_side_boxes.png new file mode 100644 index 0000000000000000000000000000000000000000..efbf3c4f8a3d485eca2601b06000e1fa43ce9e96 GIT binary patch literal 478 zcmV<40U`d0P)-eKLnyL&KL-^knRT*t=6EDnIfI_sQg({rxtSLaN#|N7L+jNg3p|2%yD-j}Gh zXvRmU^d_Srz3KUHVs2t?!s1VuJ3E_%f+l0r+rG8QqFO3-kf}E^YipI8gG!@$(9}@S z`}+MSi%N!^3N=9_6InD0(NxPclhKf6N&+Qt0&=3L&`3d3rJxxfozk0(hV)X+R0$a} zpu`nPGGScUSKXc>P>6^?647;xo_#xhBK?{PAT#LZ1hW-T!t|5p9p`b~K3L-2ju*E^JkQ)1ep^i@O zO=b{e1r;|mMRr4XdiVLhU+?-1LR>b8k4JEKb|Q?7&0alocKG31%X{1b370S#E=Mlh z47uZGm_+aH)LdQtc4J|(HeC##9-i7&?TP(Wwxg%nvMFG?XeE!WwO?%4dh*C0g`0Ef zLWe*W2m~ULJ9D?Vcyg2zhfmSB_aH?q_}l12oh-VGO(x^z>t|%^tu|H~?#@1A}DkjYKCU z+(ih1ZZ45UNo*=A1>;x7$x=HZ6aOQ3vM@3>JKKNsNKIzQgqa};O9@HH9hc$e$c0Nt lWUm$`Yv+TzvlEdW`VF>D22IH@9z*~D002ovPDHLkV1mW`@~!{? literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/application_side_expand.png b/base/resources.pk3dir/gfx/icon16/application_side_expand.png new file mode 100644 index 0000000000000000000000000000000000000000..030cf7c37839cc02c5d08cb35de9f62640063c88 GIT binary patch literal 581 zcmV-L0=oT)P)bXLFrOI}#XAMrnzM!yjS$@!NeFNp5HyTkm?RpyuK%q>=#nO`L` zH==;V1|c9pf>tvp`m*qu(YM#h+5@Fh#;&%E$O|J1=7!iLIYm)$u;VZno}ZxjRuP@|>+C(Q4%^EH7|#@HX#1eW147;PK_BBq1TB ztSj<@D99YKNph?(W`E3bY~OK?cAwzMa0QZtGz8KlA(A^$=I%s7L~>CS1&w->X#C+#Snv+#Q#Y8#3W?Shv&pgYxkM5>5!j*M^V=GM TxI=}Z00000NkvXXu0mjfz>*Jk literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/application_side_list.png b/base/resources.pk3dir/gfx/icon16/application_side_list.png new file mode 100644 index 0000000000000000000000000000000000000000..248eaf1ac1473e89184b1b037f7c077ba76ad99f GIT binary patch literal 510 zcmV*ZfP_n!43{GpZid`(Gfd*b z+4f|A|KP#fXDi!vur$~@v#^*iE^r!)CllKOw(F$zJUKk(w0^dp2@hX=@qc;r`m6uX z-6!w8M|BrryaywFplKS0!y!|L$G@=7vCc6UjX9SuoyTN^iaTLvncg*K)lx~xNX042 z)XoX&j8IKR81KRLAMa?}meFX$RLPK2p(e28SQbGhLUlP|XPMp&W|ag=;0efyqC$|2 zP$eTQy?}e^B~8P~Akh zvI%SFo^y0`#Ky)3Q#mDqfRYj}5nLivNrX@9^wyYFQX&-oDup0-LOuBQeRsUsuE-3T zFf$}!ZOg64pOHH*!_AQkmyig%^pd+XkIbBY0|KZP(ksAG%K!iX07*qoM6N<$g5MkB AmjD0& literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/application_side_tree.png b/base/resources.pk3dir/gfx/icon16/application_side_tree.png new file mode 100644 index 0000000000000000000000000000000000000000..f04a52b3dfb8dabf3491ec7e052ed1a5f7dedcc2 GIT binary patch literal 483 zcmV<90UZ8`P)pN_*poPV}fK3`pE3vW?6l<|D5Xc({VhY=BuCHMV1+hrG zRkDirp7VD{3|xW)!hTy z&t80bcW_)5_ZLUq{><*|a}%?RjUNHWWi!Y&>vL}E=OCkb`Tnc^=hcUAy3Ug~pS4Ai zf@ZZ^(RCfQR;JeHzwlA`C|tpB7x(Vo!oz6_5>3~2)LOZ!duS=Ly?fM?8MH^Wx#7jrYe3uiJoxB~poHWZ_I?<4jWG_RV^Fa4>!S z<-_K7zwuyW>&Du8xwFPqte-A&3)t=#)n##f!d0DB7glf)6EYsY(dy7=k^w=~}g0OK393~W$5=0atlITpQLO+;BL(=rAq$z+S zAfPiSKr)@7L`NTxVX}xuDVk!L(P+eEGGTXThuP5)d*d;)>4filyUeE(_P_2jn@{+$ z|C!(OIit}CDY@|K(@!^pEn^)+ETDcHG z0Jez;%!*B6r4%|KZAzGCr~^&!6io-1l?bqDB7#c-x(F=MSfc4AaVdacC4&ET{L^(b zvT6G1ufy^4k9AX-C`D!>iL4b#$i_;XMi!QkXvVCBZLXtmO@9G#_%iGj4i?)00000< KMNUMnLSTX;N$uzW literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/application_tile_horizontal.png b/base/resources.pk3dir/gfx/icon16/application_tile_horizontal.png new file mode 100644 index 0000000000000000000000000000000000000000..8a1191c389aafecbb9493f14f13de25e34f36f71 GIT binary patch literal 432 zcmV;h0Z;ykP)~HSm3sN|U6QrN-pa}fa=>kAy*54Rm aM*ISgWgjfIBP3%00000 zld)=4K@^6+dv{}4Y=qQeVU@}tM6j^36YGGDjg6qBwU$%~R)ORVZ1Ms&K0^u{3%3Y@ zASi3DyPIt8obw-xdy|`4NnAWIGt8O8$DIG4DI$UwJ0D*?ez>}QJd2wWgoGrLH>*j= z98)mhgioKpzkdJr=^j8I;L-Z(Zf|K&t}H=B5I{sb07Vc1ist;z*mi*qFilZT>JuWO zErKAB$a3eP@ytuw=mWR~n@?`DXuN!PLcxWsZyk?Al4tUtK7 z)>|I1a-*~AvhwpT{I2S?3@|=ZS8@}JuPPh5A@f!oKT{}$MV-7EUD=C(AAx)Hk^e2H4jA zqMp?=kuw0+)g#_`oi1?9<#Nbovq&bBC~8$C5(!-9btsAgS(XtFhdHm)k*NX1z-X03 zG8Gg^r3&tfI)C33bX?!-xX71rcB|p^M&taBv7`Z@X|tuRJjYBXgH$SoSS-eXXf(HUrW$71hbZ=gB zq@LsPI6|Qi1A@UI?nO&JpATNI7aos?^V)2(0Wi;h=Z$iuigL{bsi-}bDj<2`f<&uj zXu|-!oBL`^RX*oPy+3+`7O%$BV#=F5s5ZNTR%-+=hQq>kNSrJ|)Q}_wH2fMH1v~(6Q9)T8`;*=P O0000CjNr zUW1fN1d-Gd7r2N>l%796-}n2KALIT2^YO?eu@~9M*vzf-7i;%d+Nwx^J95X|kPDY1 zGh9Mum^%l$6{Q6;tonHam& z&u-m)+9C;(lg!W0^P=Y{J$aeIu9KK&6b^;p+My?$?QijWYk;}0r)e}Am>WqzqNC`2 z&bQ6)?2D%u>Kdo4V?>9yzpnCg;~hszOJrF_;)Rg}bEBg#TjxYM(AWKi=r@UR2yLC= z^Xf3~moMO(#>D=QByLU;NZgGixEo2m zUZ+l-#NFwTM29LuhehJSZEZZ_k>_v$^`U`{uGrzP*mgoQg002ovPDHLkV1oRO19t!b literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/application_view_icons.png b/base/resources.pk3dir/gfx/icon16/application_view_icons.png new file mode 100644 index 0000000000000000000000000000000000000000..6a93cdaa78cc42caed19920ae622af7e35f6067a GIT binary patch literal 476 zcmV<20VDp2P)yh(bgPr6Nj-nT19X7DZ8zeUKOl_Tl|>1YLMH z=jlD?b+Sb_xgR_*#(SP~INR$20GAV7?rFuloUPPDd!HchGLr8gZI>aqRf53gD~KB} z;7=4_D*g<@>Ld7K_aG;3>sUvEaJphdb1M87A#!by06TZW*wPh{Ku&%@CmC6|-~wsq zjb0RsMFKOF(Fjbu5Fwh)ru|I#tR-Lz>qIaxcgh90?Z1KrCWc|y!1T|aZ~=a*-(Ag4 zSPUtVz{2m+IDzS#IpP9w-9EN;RO;3eG#U+?z$0h4Kv;Wfk8B+i3#{n6-UibhNOQqt z?12jeFM)^6#o@C#4HjCL*d?a8z!%N)t>y1HEak5ffl*Zzs?{nz*J?G;G`=UdUjg$j zC=)9;^kAC{HL0z0x7{1P|EQ`>eA9tOij?;P^H=75o6^EkKQu SuK{QP0000x=~R!WME*cb6K0H8ItD70ARH|h P00000NkvXXu0mjfzPQHT literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/application_view_tile.png b/base/resources.pk3dir/gfx/icon16/application_view_tile.png new file mode 100644 index 0000000000000000000000000000000000000000..3bc0bd32fceb21d70368f7842a00a53d6369ba48 GIT binary patch literal 465 zcmV;?0WSWDP)zJNu3H-P zO&@UpeyZQXi7jKe-Hk?r-sue;aDce_XqkvXP+W#F_*ot`jB?BS93Uw71|U^ZjLH`yP%FO7U<6!nLCG} z$SDlWwtp^MwsrC67-bFzu!t;6Q^%|k2MJ$kfh*aj@vhNOIJ zWFxBVQIH79u!vw98!Ll~y$OKnm}QK5wtxPNU<+B6{mDR{T_7M%l&baHE>bEbHX04+ zn+OzZ0e^b{APT{9E#RmJ5)l*`)B%#z1i)YIM#v1#3=Jvuyn6YS$$CoGDq?9U@APAh~ZOF>jp#TVKsZ^rDVDQJO z=z(unDix`Pp@6(DbUGbswOaq~fE^0}P{J^D(r7fOTCGyOUUzmBMUy*UwAN0eHX3ch z0VGKh>h*fm?RK3*p0=MB(nc}0O&K6sv)ObGuro)jd=1C!>krB`s44?r3Yg)uiG7!8OBL$a-Fo@&0(0LjNH2#KGJZi@q2YVKu xMc5!EfO4vTMwnf`nA&W_@!!aPwbiWO`5Vn?>V~$MffN7$002ovPDHLkV1l0g-PQmA literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/arrow_branch.png b/base/resources.pk3dir/gfx/icon16/arrow_branch.png new file mode 100644 index 0000000000000000000000000000000000000000..7542db1d1a57f9f3ccc6d5d4dc82ddada796e67f GIT binary patch literal 582 zcmV-M0=fN(P)8HN)#RH5YnYUGP-mK>R8bw z2t8C_N?y`%B@?pVvm%P1(=O${na{Vw7Aotm+uS~f8Ro~wbIxHo`d;S7O>X_I!*}m4(;rQL3lRx0{4$S^45y5Zuub!<^(wd zDg1Ydq7a)PBNSH(^bYo1I&!_cv8F)Tfk3iCfaGzKcdABUEYJ~V4lNs7(L31l-D~h- zlLeyC;Rle^b>Pb0!o4OezZxjWAc9)nJe_NP=QDRgIAC4B#i)@%!f@-iPyu79xm3 z&=Ei~gdfA((>G@?t|CClgk~>+;;$k`$HzXCdi?6@>wW;(eSTM7w8{L??AcXUU@Ta{ zLrZBBKD>>O2Im`9qM4R5P3BW3krlN(mI5Z z(KV^C5HyzvLrS5djW#mEchkd0<@IzkP&T zje~)eD;&7qVC!q^K`R)J4I}kERX%bq_9+7Zgt9nQ1hjexG(6abiLr9H+N>B-7 z2>SBph(duFLM%ZMg!96nVfPZi`0RE{To_%f(_e%DKo9^(nOQLYoR{*7@^cGNURr@4 zzkZ(Ce|2}YP~a51^_3ecKqY3A9#W~)94RvZ5Lhx&%iTlGqzqJ)REFGQ7YYk+-h&8H zSWpD2LHy$fOifSwLOD8d@zwpm007W@bKhnf=_J{@wR~IV`r=Zk3O;}Rf{Doq5z1{E zIsfv~>-Wn(Sk20NF7Mj0E;nzqrn&}V6|v_rc**3>7Z)bS{%hr>c-THN=6y>p_+sGG zVAk^%RuiWM004bvt5qlzG?JaJFPIi!hzCPM5F-#u+HVZ3^__nM0fhdEP)RB*?~^j!LKVQ>(O&A{Xr%)RXLn#U zs4LtZ6rCMFY5|B2$)yG$6aaIFPbXFR5;7s zk=srhQ51%Gi+LO^77wV16dAzbG@wAMB7&i`(b(8xDqyU&#ij;pOFf{D;3PUo6_qH7 z@zCD%DY)SY{?6Vev}G>5=v^;XviDy5`&RNV6#!MZ;uAv`-s;%-AVco=6~AW@oV#X; zoCz$&Z(d;jHilq%pcXjuFe4{!G(v;>9DU>S79m;;B2ox|%Nj+MJXx5%p2GUiG!j?S z2%Y&cbj&LR9?=RJ#?#^`7Ar|SI}E|PVW`sPXn8=Gxtzq(^&D1yr10dMQz3B4@Y_lP zuSye$7RF#%H`Lg#dZzwixa6krr|(Pf7aR(KLtwFRkwCIM1ACSQfoTSJFpr@l7akX# z@D=Rv9@rED+g2a?Hy@G7U^9C3eb%8a_?P-$1a5i9WKAS#+qN85)~E=vH{A*SvKG1z z?dVFiLHkbgJ49E`%y@DfW=~%tej1}mHwt<_YB9MVMN|yeVJaZ7Jh>K;f_N^45j&cq zYibm9%abEw2)<1>?5kF^y-^EP;Mg%$3H-V=jgh?XuO0tco$p(rOKHJp92n09(Vu4V zFxf1qxGkd?5d9d=dtu7-P^)33OCji3)S!K#g=w8v*PN>ytji{-6HO9rn%8(HWsOpaN*gR#GpYXhHKL|EB8l4*TSU_vTR+aX-(Oi?S;8XyR2It;Uw(aI)9^S|=&95eX@({k9USGy;sUSUzeJ^< zMds$`SXy48v$4bI@E9?)it=aq5A%!jd|dcIDK=`4J{pRP&HSggJxd`56RH!pk4D8J p8dUC|epvAzhprq*3?{^oguj5GN{z3E7kmH!002ovPDHLkV1kL#`6U1V literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/arrow_join.png b/base/resources.pk3dir/gfx/icon16/arrow_join.png new file mode 100644 index 0000000000000000000000000000000000000000..a128413d8892dede67a722b755a0e5a241e22cef GIT binary patch literal 626 zcmV-&0*(ENP)rYsPY01;xw|q+1XP62ZKNNf0i}lORw#-+^ z#eWjGI5)D~*%m(1>5Uva|KRl7dV8+T7A`G}x7k6Q#1cL#?^nclzafIHF=frdfxTM;5eU`G(t3ZL>h zq%#>uD8p~AzniHE4Br`SCb{0b_i(V?*A7x4Yp)<*$j^%sM0Q8xU9lJpTqqXT@nX^1 z5K1V0^Sv}x0%NoVtwF!n4+^nruOj~?pIo^7eBkL7YanOml9_B4qKQB-fL6CVNJ_L8 zqEZAEp`_BgUC2WzPE>s=#feq$gGR5;6H z{Qv(y10{fofkH6I3@AO3$p*x`Nil#0jeqs;pT9Ds7{CaN1)$9r#n~kE{`~pF@bLXZ zhF?E_GyM7i!oL`P0x_8Wj$ni2F7#hzWPxfvDaITYg5=lqDRUe#ScX*(E2x=9XYzD6%FONbQIbA#VsuBq0ij+PPf#`3M zpvPY0@wz6#pQ1M#cCJ4HtBQCgjp?eMD}Ow?B1lUn;`#{$MeS% z{6Rm$gJCR2mS9S5Qr^HNj0iI6M|{5JQ7pJHG!RSBu=Xz)&p=c#F*=4sGKu^2{X2Z< zASEEw`V6Q2&NEMPuTwY#5DA1Cf aOZ5%-nC^v5N+ApY0000%pKpR5(n-OJ3xTo| zzV{Az-rC_Vje#(D=jSF0=P$d$OcdrqWdZ50OISNyhHKXf!jg068_0ZrhDT>{L~4Gy zBdqY8Z{N|1SMT6qEsm9X5`57DGIJ6{tUiU*w*<03GFWKb!_-I5B@^$yqd8xVVYQKh zR0+dTu)vlxgG|$F-~JTf!pHvB;^}=nIGMw(LqWZ0Ajmc)rbZwghz$N6FuFDPw?M3V zxyd6>bK=mgT-5{T&WPHE+aleX_AmP13}~n2@i(LDRmJ8PMrCl_&@?^QbAJr{3Xe7{ zRYXL~lWa_vCNY#Ts)2%lP|*kDnyzJ7?dSAQ`{;tavxCB5aI&_5*@FmdS#$HE!Hso; z?9Gj1PKm*v6<|v1p?jjC$@D`cYYE)_AVDgN3~tc{;W|CxdRiyDU-Jm$-Iy+k=wIpu zaqU^Lc$`4uXdceI71qtpa9aZ_T0~1>NOA<)R1XMW9DzMQjIr$@2E+2ogl@2IS%W^B gtbN=AP4XIk0RxY;jV+3>Hvj+t07*qoM6N<$f-d$A%>V!Z literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/arrow_redo.png b/base/resources.pk3dir/gfx/icon16/arrow_redo.png new file mode 100644 index 0000000000000000000000000000000000000000..fdc394c7c59b83cc2b876abc41064c75eb365877 GIT binary patch literal 625 zcmV-%0*?KOP)FZj9*=u@@4&g|7erBn|Ebu&JU%m$={t4j zMA?=F80s{QH%n(hsfF%mohhehBz1^t6ID+NGJzBtYm#sZbA{ZEu?vrT)(Lb!?K~){ zH(Aw`uB}Xq9=*Zczi=_)|A3QuQ}znM~D7~ zjUb95oVKv23l4|e@$lZ*dJFeEA1zqO!B_8JKbXnR;M>>lDE=(2>_dXN zph(~`!iy8(2_#ButL^3%VaH2WCpD^U)OZxp@C)2#hU)y+@T%ZNzJigNk%37 zz-WYJwT%teVfiEI+B*@v4ey@58(ld4VY_&5-ox`e@AKg+0U-I`y79bmuw_~y6+4rZ zBG5EdFDS+@M0OSE`>d7SUDOzKZ&h*4eB1iX7tOd9RiYtW2mQ--bUahxr1`i{RG@dM zL#}_X=DDO1{;UI$pFu=dLYT_=5d8WC-sLfjr7UO-HKMAwa=!>)kEhvuwre zuW3yF@ZxFCkI*+ad|5kOX%5zu8IQjhan)UqgSrFGA_0nQFn@Z08DSEUToCSz4Z1ls z&fDbq$T&7|6iq$_uDI$@q1_kQ@dfqk*0>{SDL6V)94@)ete)j++*>bIc9sj}Y;R1o z#OpH+Yt-^4wfv{nern^iVag8-LrYk6ae86R!cq$1)rW52v1)b7{)|O}AG6Uw?DO|Ft)k{$F)%(f{RF=l?I+ zlJnnhy4xL`1{54hojLt{-~Wv_SN(53T=hS3efa;Fl|lb2w&(vZ*_{2~XR7ONye`Pu zoA?0e-~T}W{*PZ9b_gaOFw5hT_Y~(tZoT$Qj_p>QLT-Dpnng!_d8sIiCa_~9WpM}{jZm=`Cltb^#NWN0R6i=Yh}{^)FrY1 zts6}Ln^hV9kC-0#zxPDb|Kx?y|5Z~IXW}#f=--za%M<=jKim6%%IU8E6Hm4O?>pJ@ zzvo2be~`FJvceg~cv%O$F0gC1*cmrB?0?kE;Q#uCTK~1P)&8reDgReaQaGRxhpHK8 wAOih+0O;RKWM?MbJPl^eOx0CX$&G|C05z+&w|oy)!1^@s6 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/arrow_right.png b/base/resources.pk3dir/gfx/icon16/arrow_right.png new file mode 100644 index 0000000000000000000000000000000000000000..b1a1819238c6de8f9e50988f4151261fa6ba64ea GIT binary patch literal 349 zcmV-j0iyniP)o>#A+qW*AYQLZl(!&BX$x7Ik;qO170ssEM z@$bKXf%rGW?|(r27bf-TSv zD}TdX0CM*JhkLO)8|Y^+n~Q^sK~hqR;q|N647YFGy>NTZJsWr!5CaSfwJm@a><8NX v2&h?|*nn(6-Ko08>y5Bipj zFuyiPrdN8pDqvvkw%oSbD|$YUB3aMBizpn!0@bH?0kAfUJ+m=Vt{!e1UD z_AQ7AnZ&Yq3oU^QbQ$1o#v~>3AqYSCl3VwJuGp2*ve%Mr?A16`oZg&5Nc6*_Q~a<`f+n=r+3NUh>M=H*cV_-chG}N7Vspn9Y`Se z0C&>eX!bRrM=;=eq7!GFC$R4w=n|A@e`7&l%LDhi6W$FLp7k-fKe@oJG0^dCs2ftC zB0v*S$*EwIXr4EM`7n&hl5iB`A4lL?b)cQ2aNKqjRZp2DO_QVx^`6pHR5;7E zlj%-cQ51!F4&J~xM61?D4NeiKN{NVy6X-Qqxk8=MfEX_jL}^8BK|~N7FhJC_i5-lo zIHJodz)CX1Y{)@S~!d8q1l+bMV!}{YL?7wC( z%edaW=F&F+ z($9?`K8YY%uR)_%0MQCxd3ndPa;Y~P?U+0ni$XZM7r6Hug|3%ZMP*Zkl*~_HJgCLk zA%$#B#@zrWY4GPt5fc}9icOq|ZdVP>t`f>G-FQBfO2-8VoE7L?C-B-QL8&<(Elc$< z9F9VNpaHd~Mzw{9XMM@!tpI_e9I`cn>D7RVpdQ8}3WkFbsCW7qu?h_iA<}x2LUHGS zH_L_8E5^i;Hs-n?bM4!dqv}ItRGh3xVBa~)+_!mXcGsfbDMZdlCbCp%NFPW!OYKP{ oAG`}3ZPvAA3WJ2dfsV78ToP)wU4~UJxT^#Yl8pW;T)B2y+W_BqqmW z&#t|w0SE!KR$a#7aL!?!V{G>0(f7&GF0n$i_yAiovkXpE$M|c8KDe}2*w(W8jK3Y2*x)V03j=u2XF48q6F<0_UD&z zFmi~T?K=p$491faq~>RsPR$VB89_xzOpK2V+=|x$1lD3~x!;g2Mz5ELE831k>xd528II@{FM*4t5cwMI2$KMmfFm;RN43xW+e;$tzEyd|PV<@i4gUfKh|U-I$hymfQ} zt?kWDj37pE;wZ>1WHG%+SvbnRqEaTN#u*-slSm{u7_C6WGBh|el4$>24G=QE;Y9f< z)G2BOvC3T5Jn;{4ig%R|E{ITA5W$|ds8uW$Z^f(HeLnnp>dACn(D>^wEGjH6Et2~F zjpx1H%%|rOCx{iqDPk27MT{DNK*OCgPK;oDLHt!jVx&(zZS&Lq>Ld9Y&Ck!LvbvJw zmn1{|Z(}o^vo(KE_?L8-a>7*bay4g1#tO$)YSGB-# z09u8rA}2Xye`S%*{zU3D^_fPdmiyPg-%=noKoSatC_xfp1wO}z@<18F!7w5ZBTtQy zk>Q?#Vu_u^$z|>m7x@d+R@cH9d2;6$#K=oAGXHn~_+m9`^0Ksl zybr&x6m>QAki2vjRQTUKo@})pZ5^O0;;V6NP3$@V;4k*yCND4)s8xvJbzU?;j6jsI zmJlOe00i|<1M%2^mY^!=O@UVms-Tw!6e7N`0#c#W>-;y{_WlDAEgOIU0000T|{kC~{~#l_0}%A4(11APN%oTu?? z=X074W`VoO1edlFk(}Pe+k{l13cG z@Zg{ebmFvrg4(aE)ymt0PXG|#hrbo`l9pd&CJJNeG5oRLh@uE|LN0g+kPAk_jD!Dj z_W)6I$xu?r4rM_XOv2giIes?kpb5$I1f+0vQ(N0DRX_d*AT>Qam_gH;poF6zhu1W2 zZM?3O0ATjZ%VV0p@0F|Xy0#$W%*eA545VUQHZIT}1^_dzn{lzTg$Dx@C_=$eZ`855 zuv2PZ+%F%lcB{7yKrj%JgDv*_6XP~T7zIHv>jS`+?hIW08PEt5;h|3hYY}w9A7ik8 fw0GAAdk6dl5~BQt8lE;000000NkvXXu0mjf^Ze9L literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/arrow_undo.png b/base/resources.pk3dir/gfx/icon16/arrow_undo.png new file mode 100644 index 0000000000000000000000000000000000000000..6972c5e5946080ca1dec4de09d9430d3edf6c555 GIT binary patch literal 631 zcmV--0*L*IP)`NY~_X_4^RN+9OmbDu*=G*+_}E z3jR}&gbG0=R0#?Z-=09KI|YP8=#E5@+>uO|=1VUCOole%Li*0J2^Gy8+;b?&km6gg zf;aDGp1r#I_V|We$e$~WifFF9R7MCMwsmwsME9<<@yx?a+v)qKuKbNe>k1{IrVt}k zbbSs~bXr8Se}V_b4opa0GhLA`RHceaP=N}IElbSa8@d(ij1Q|4CvOirm96w#wHUuW*nL5>vZR zlg{G&%mT~|kL3ei%GW0*UOHUMs5XI$4uxe-L?I@SAefq*207}Iqtjm#e5*fP53AiC z)C|RQfwzxx<#_WfANRGZx{+tFDl8~Q?;~Ve=lM^*8UTTnVL?HTDz8uta0D@d28E9S z_)i8aLz^UE6PPKymi;2GJ`34{eIia-CtfAt0H61rk0 SPTNud0000*uQQn7Ao3L@HcVN_JG5Oz^iELqtfic#8+p{{13 zB!rfdf2k)SDwJS|D58iKOKXwBFIFGcC-AUOfLS9bv(H0S%=6T$O9SC=2fMD%gnJC9? z!Kh(gvt=Cx?1R~s3W9x8mCUENrT{!2(+x==*z->Z(e<;6aicYvPErVhHT_;HRWCrO zX>Ant#Yi-31=*-(@?ZTrNtR{}?1a^q3-ss0eBi>@Qc)edAUbFFjhvR`kHwNKL}lr> zmx4@#VC|1-HQcog=-UoF%!Jv#1q7>sa}xhtBKb#7NeGlV;rH6OFmr?PNPiwMRD=jG zfZ3f5vy;Gqe4sZI=uW3=7L4|E%(QHx)3_-#2chPTcz1*X$TTNe2v#yoR){KnCQhcg z(YBd3W>A0&#{D#mmPqQSlM)|3A^ATXx8dz!8(tOJd5pyIa?we$G^;NU;SSgD5WO`G z1giu)7o5cCBA8D%u7}Z)i7#g)f3PVT=*fasvkLEz*?bEIkm>TthSk)+f{EIdAk!W) z?VGx_0qAlea5(`l58AzP0|-{W*Cx;y=hMVxgG_4#JISQPBo@rv^)uedmP%+LWdH!1u~sTvRX(MC)0C( q-3yOhdA{Gl2X{NXPYNCLME(Md?VydvM~!0u0000?P)rx$R<IWI`!e`47o+X|cM zhswMI)6H-!+|Ry*GtmT2KZBZTgf*vuh@Iv~E3-o`X2T^+DyW5TGfmLUU@4QG+c^0c z#zg&+`J#c@0((YV&ur`*Iawk7JMET#>EkfEJtz9cD4oNF6e!0Aw?I&|=qKwHAy9XoQ zA^YBJr@&gw)O7(`yrYQGx{Yirh2eMScnk9(q^&}_PQ*$`FTOgh0*()5P;Djfw78dp Z{0&Uoz&aZx@__&V002ovPDHLkV1iM?Q(XW6 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/attach.png b/base/resources.pk3dir/gfx/icon16/attach.png new file mode 100644 index 0000000000000000000000000000000000000000..ea897cc9f18ca49aa0f30bad4e6b67e4afc7f498 GIT binary patch literal 391 zcmV;20eJq2P)`oHYyCmI1nr3DC<^9@PyNudrDc9~P$75b!T6T2tv<*K=EzTZ+r6P_ zRz+%oP};s~_x>mm z0pQ)E-O{|Rir?=|;*4Oe!&-;44r3gf)-Iu~;|c?9A1D^Up9`F|I42nWf1;W7*36nQ zf;E<>;mrl})wIO~mSnh(rWZa#2NtdEEaCGAoUuGEYF=CvMF*C~(sQg&{KX2n%}a}8 zOciIa_PHI{);|Uxur%sZTk(iBku+YSk$2)hv%D-q|J4zkv8~S}=sv#n$c;b8Tl>=) z-YmU{U%3OXd?U497niTyWAILy_At!M7x2Apj>MrbEUAGs! z2*LgDY3~W0-&vFXRK&wM!Rq38<&LrY0BYvaiV-PIt`q?gL7d=KY=+X85uHPH9zBu9 z7RL}2PHTd~U4qGM(<>iJyKg2kEiRMk2-UR2{gu0rAcG5XIGqJs1my@XYarq;!Wm6| z;5%{y*&m2<7C?yz`F2(1ES-^c+p9yX-baE5husHL>x|gN$EFoidu&lgFg_;qBqAn^eBg zmrfDE=lozB5#`f+?N@-W=9l=-*J{u77@tgMX{kLa7Z#4ze?Tq%=1F}hk fKwICJqlf+jPqmTX#t3U(00000NkvXXu0mjfGA@$z literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/award_star_bronze_1.png b/base/resources.pk3dir/gfx/icon16/award_star_bronze_1.png new file mode 100644 index 0000000000000000000000000000000000000000..658c7117bb8c5f7f6127b82725880898c3d7fbb1 GIT binary patch literal 733 zcmV<30wVp1P)5#ZOj$V zV$6R8et`Hsp^Y06t?}x?-BN{Jo+A{GLpF=}{yzmtYh)C=wic&;1MX^#S<^tIK8mw$ z9j5mS;s?n^1>U{8t&EN(863h(*qFLQ=;hn-R;7@>ex(0vvZCi*>q5p75xCt@M#zpM z*Z|q?@X7EteIjT$hYlRP@ApxiZy$PlmbH;D0hOKL_{*WZ;MR^|Dic+L1tK5@y>d4> zXDufE6I)H=Wxil#C-axq0i?$W%}gE53ocb3M9Ce~cq*pr4r68}P%}Rp!|ZI1=W3eKQ{(8&6eg2G=4KE}@YE!+_s=wG z)yj?Wi=|CWjtmfUw}tvT?>o~yi1Cr^9Fogm)I5&s5bN!p#FzaA_^&C@GMJ`fX;)}= z5K#fB0E~v<&l+~pTpQ_Hbc_JlkpsFSk>9$Ch@B!-R)IDix^hJgZHdi`3)**;A=W+} zt0nUFG38I&2bR2ge6xJwHJ&|-TDl&zbzpIUHhXn+ZJGP%0^v7ruA^itSBHu$h4w+w z&L~mIqJj#PGAqhVOEX1tY{nVK(RuHFv=}WVrUQp_xcB^j9L~Ad&|0%#r=L{ogPY3f z4!uHZg;a9h6+#J0a`(`5{}%0Mo*4@oH;YU-0;QA1Qb~kT^YO3Swpc8|wFF=bv<62? zY$@0n33K%OS8VAZ?>YLSi`>qj&9`d&Y*T9wm4vIN9j zkP|P4lYpD0Bjgn4X$;UBv_dZ5O~RdzicMmQDXe%u##|`bv~(aghASFAo&;Q6a|ogD zsQtBmS$G5$4I-kGsOcaoK83aupcO`1Iwk`5hZekp0}sgXR2hFB(%HO16fJ6JWl^G_ z5*Z#x#>1$11U(Z)8yZW5@V|X5iHUle#xE=#VqkOtzh{T*b9=LU>LXg&=(!nmB90QX zxIJ$Cy-!2fx_m+W&lac~ijkew;hG*o3kQS)N`f;V)7&wxjdrA5BLJqiLS`2yQ;)!F zMsWGEk;+2mEGwX)cx!4v<1QcCI3WFN@qTL~^HJkK`pdQ(nZZsha~hGg4x~|$8X(m^ znUU}Fw4NiatLr*KZ{zAnwP$R&Jfo*|RL{EdFGe#L4Mh%X#Cm!=lt?e lJ9R~yy?yVmASqoe`3;e&U@M_8ssaE2002ovPDHLkV1gayPXYh{ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/award_star_bronze_3.png b/base/resources.pk3dir/gfx/icon16/award_star_bronze_3.png new file mode 100644 index 0000000000000000000000000000000000000000..396e4b3a2583924c56773430b5f2a5de992bb696 GIT binary patch literal 754 zcmVD`bm3d zGTu>FRh`dR#u#|GJA}tuhQSMPp)+>o{OWh73pXD}T${kJM?CzXpH!75YRGK?HI?Gz zo8Fw@!L~jYmlqicA7i=FXk;H0N!9s3d(aspCafT z#S#=yNti3b k7t7WKJKJs|Y|BUf0tz8#4)XPX9{>OV07*qoM6N<$fPbrirq-~0P{ulMSj*I8(*O_yaV*n;RGqTmwM3Zg;V@I^LajC_gJLk|%viB%8v zXb`=WSiKo*!O$dgOXnuF?pAZ*qAgv&dGGaluiN$B-}ley!894P1BY{7&gcABA_Bm( z?~coX7h0LTvWPQ+wGL|?&N_^7JbvF6`Uihvy8k7`2JzP%XD!YNM*kaVR;@LwYK&lw z z6|B8&1-9?(`Rg>qd^(dwc0|)e>Qg*bJIY-(QKo*L!x`K6zku-%b{)C!d!}zH9q?%4 zd;F$7MCu-+Gcv-Nb5}TjDd@X6xc|tl02Q9v78mi_#EItw-ukiU(4npq2e)+{gh-U| z>Q@Y$^uF2Gk$y)cf^&k^rA*VFg{uInGS)aJiT14`AR>qpBFQHpu^rKQL>JJxG`6&W zpm16fF8@imnC)qKMFxD63wm7;40;{Cwf@#_Bn)t29;dTlOQ0N8ckU$WZ^9W(VfqX5 z)7fLh7y?itLSaC)I?M6sgS*?jdtOAs>xj9DxDsMlKzRh;O%wd^3zem^SWo7F{-=k{ z`)chH^Ixi32cO3udSkbW)#FSau_bV2GL!QxU&``8YA>;tPFB*x{C0B0=4UP*Uf)8p zTW+X$&4@0{A_@?PLV;NR8lB|+)LyDDkD)&6Ch^A*&D*zlqU5l@aV0|a^Hs^6DCOgf zK`&h++R%*77O8G*f#+WP?+4y)!gH#59grJph&v(W)pbxf^C7v3iCGky4lN>GQid~*jzV&2Y;Nxe8 b&C!1V<3gG|1vXA400000NkvXXu0mjfBS@ei literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/award_star_gold_1.png b/base/resources.pk3dir/gfx/icon16/award_star_gold_1.png new file mode 100644 index 0000000000000000000000000000000000000000..97a22b72eea2e8d65655993c68a9e03f6a40aa9e GIT binary patch literal 753 zcmVPWf;dl@9%f?!cp_eSg3A+l4!Fq^t+ti}&IAe0X@D=QWZj zM%;Z?uCWO_G=wDZ9(j)>jD55+NwV|jvC>tN3^K{^fV>&V*w6!et5~&pa*WZwJy*mn$*RS=E{iBzuX~I|52pZlZsC^BkvS{J~dNA2rd+&Bn zDPttzeo9qHVOn0H7x@0?K2+P{2W3YuKv0gI{t`DZ{% z^)uSl+#vB}3L>aG4!cswJw`5%TN)=W%p(lmIqdQjHn;eWkwjs@obZk>!UG>wB^pj6 zJBPQA@h%5(0Th8rU=r2%$dMnrMsDoxS0p)Oii?!LYWDh=q4NEw(&6(bk$r@sRpbjO zUIP;n<+9A(?2qj-J%=u`3F{W-TmM-l$V z6zWcE#Z*)dyL<*2KpukuZ7vZZD=nXBc*ijUh^IQs>R!T_1d1YTE{iGKO;BD#`7_Tp z-nnR6O6#}%g{8r#E4*kAYY&kBcxtMq4O+!H+m&<9B%$t@BKNE>6je&Y}T$>)>rA=-mG16ocaoM?$_R#KKptL1a;2QYaEZL?ZqH!+`{1Z+cmQ zQ1}3XixLgQQmBz(W@=0D%tV*%@ux?(vz_nL)r+<|qt*=^_D2k+IGc>M2?jCYw+~gHPWej16&S4+k!e$e1 z8c9@6m=~ktaJufDrrfG+$c_;0J)+AXR6rg~4wG9-^p5hyBV-q^eLX8w@MpP7yr zI9b1TYcYNFC1gjDpGL8Q!VH)cpWS8T^zmRH(%bc+_AeM>^BXFW=c(D>`upR9L6DHD zC{{rhL(1sa$1_)@d!GESEwpUYlqoDZ*YYIB z@KEmIZ1sp^{p%0ukJJJYwH*M!esx7LKIulW$P&a@Bxzp10@XKE-7~GSi1H( z@@-F$4UO~wSO2qv5d5>I>G8t&$-Ru98~DgOHgvwPo%gSox^JHNWdP)CrU4o&u6xvM} zE>!43A_c(|D^&=#^_8j(DoK2_jE_hv6Jy4XCZqY^$FGYRnNZ?^!{r{%_q&I4&NY&l zv&~qvd5Z(RR~bC;k(pzXlvwbd5QMWYK{tDPH|x#` z?|dmjqV)3WHS2M)r?Ko39dCYxjXl=-S;5x{1m~G9T9#F%v9YJM{3q7c-eIY3^LBNH zsp1UYzqSJ3^XKq5i_=M(Yo4+?HAJGel}(jrSW=PV^0hI7^F0d+ocpG&d*ttlp36fy z)|dZAvTi$xMeoy`=;zAyQHKA@_1x<1>@H=DB<#gi87XQ|P!t4TTB& zq=+B<$dU8W&pVoi_DKms5Z)Fi>b5_6U?dTrts7H$<8lckp&$}9A3*skWS<~gz)lX~ zi;ob7U@h^p`^5Rj9Yzwx<7P{+^hQmeRwkG4L~)J~KOxvW_#()GNn(;!1ZOD>9wk3G za)LCw%-kXsj+px3Ihk6stsz>m6~*JoO`}jm{yCTkmw!m^)G;4Fqr2sM?Vs1g>W`Hr z&AJ!&`uf7tn;;?0pfCf9F+`02dMs~eXq$uoH-(y=nlhP+ep|>Q11MlHAdfNC6e;g@aPD2@LIrTdYx{lty>00000 LNkvXXu0mjfmic>9 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/award_star_silver_1.png b/base/resources.pk3dir/gfx/icon16/award_star_silver_1.png new file mode 100644 index 0000000000000000000000000000000000000000..028a54626a0aac09911d57f4fb475098f5a76361 GIT binary patch literal 714 zcmV;*0yX`KP)fArj&{$f(hg~Pe`ob!G6yckK6Kt94NpER>OV46q( zwTmK1MDR|u>fiw2+jr1@{ldr?4i=8Y^YdUCI46;brn5x|u-6D?{1reDs0=nX;Qa7# z{-z|i5};F>PJvxtr+|jr4WpeM7@ADLx?BL`G4|P6su+9mLZTNX2qk_wz?^5yOziHWLHFBXekkbc}G;BKUEEtks` w1RezffuwAYL?TI_&v!4KPQSq&*j~i^1*0~MIoPHs^#A|>07*qoM6N<$f=#+TMF0Q* literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/award_star_silver_2.png b/base/resources.pk3dir/gfx/icon16/award_star_silver_2.png new file mode 100644 index 0000000000000000000000000000000000000000..e487c3a19e6de398863e819239a594bf033c3547 GIT binary patch literal 734 zcmV<40wMj0P)lhS)MHDPD zN^nu$NDZ3R#lmf9$bw~4(f#`U_MX!ux3B{*@A=OAJkR%@=RJa980fCp+X>@(D2jzf z0h*yh)3v?Oq3S9wxGv$ri$}=bc`tN17W6DtQK1`uz>KKs`d}@Mb?m_ z5l~a%)+B`G%d}UZYJ0Vg(qBL!0TG8Fnye(EVnhxhU+6ij>+NHIku3s^xm+&ZvfXaS?(Qx(lHG8@j>qE@ zrBW%HPN#n`KMo354zw?o%jF6YC#R>Uv)%JlDwU1JVkhV3=I+rOxY*124Ljn86uv6q Qr~m)}07*qoM6N<$g31I`ng9R* literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/award_star_silver_3.png b/base/resources.pk3dir/gfx/icon16/award_star_silver_3.png new file mode 100644 index 0000000000000000000000000000000000000000..1d72d47247ceaddb46f918d53ec4444d633912f6 GIT binary patch literal 738 zcmV<80v-K{P)Y)`XtzyIql2{sy6=Hu9+tjql+xOzk)<~?R3&ZZt%=gXAx2x3abu`xKgN6FU ztvTdqR_-fsPsm+$v5g2F{&wVy{xABFA=M z>Tg$mz@w??JKYAiqlT`oE)2OXoN={bDZS1`^p*q*kAjg;*-d@vV*wYO2F~{MptG|R zZl#Q+58tqoDd?Z$cO%UhgO)<#mU{;p6#;L>jklv)NFsR-vjYHa0e}wY9}S8QZ(dwW|Fum-# zX2Z$8|*3m`ciVNwH*EI!K4;uvAKH6fHzx?V&@^We*)X?7dsir9(vp z8s0qC66hg_FvDdP+YZ*QQXq*asiJ^PAt__udR03JSKMNpvg7nRd;*rSO>RS?^_43zGp9!-$Vr8Z;-c)wwgHkS+YjrxEH>PP4=o*Ja%j@-qQ7nuXR|G+z`F#G__zp#^)oN!YNg~y1 z^~|0zhm_4`@5r+3Xt&!}L!nR@MFO-?D2!7|UpJf0T_|9HeV`8KcGd}Kc-Emip&y|t z_#%p8-7t&=E*g!lG#ZU>nBYAEj>EBt4o4jhM;RJ-I-N_<7<3u_xS}Xbk7%04w(w;0 zJ9vZz;{qIPf*|w*bT@RBO#o`l2JF2T=VSmKyFa;k3+QnBw+YIugUjVAvW{-In@tq= zcswQ8$Dl7zB!&WY@O=0src$Xc9HR*Gv(tqJp|8MRP(`o?-T@Vz_k&BxWbzRI>pqdd zgAD|epI0;lNkiCmk4uxq&x&fK#JHU*5m%y`?~DO@!TL22^LGT+1A&?K|( zYdz4JEapD|xm?ahV&zG!d?u55n@*>{uB@z}*A?8Dnwo;o=L7kmHrYQ>EDQ$2$Ii~q zd`nA9Ua3^3nbPLvgs&1Mmc#j=S+0$#6I6p2J&x7#la3=BZ8*W3I0`k+#& zE-|o7CVN*zRSr&1Ph)(1yfhw<7e}MfieNCf-{bKJoKEKsN;uNp-Mv$%)0L~$>fO!F z&E;~ryo4Z-NF+mrIg-ib2Lgbq33;9eRjUbwLa^CvA_9TqI8nP*jyvY+^&9$gxY%}T z{efPLhK7cw0$_M}cqAMSm-_wwVz=8Za5xKu?O?- zc^F2;5E%~Rr1;RY0$^}(P)Go{TrOcC5P-#Esb({iSk-Li8qMj?;hYiS{9~}CObKSiQ5Oj@%7N~b%kV2yzWN_>s$J96xdd!ErX7~R;bKQW|LpL2;YAlw2H{OX6m%2x z9k^~Jj3Ckr9VnQr!KB%;i_&6Q-*(XV^lcB9Pu|&GNonSO7$7c6eYa1wJ=xR_(A>>1`N5p7 zsCYibaSEm3C|Z4d`qoJIKLgO*40(CD#Kb~u;S1PEWOj9F847I;D8ro>?l*53aI{A1 zw@@0=mf-t&P#)*lE?-*hbMX_6_(>;&HVm-K$D;kYD4FDlj`cs$<#J_l7sY6*DV#2{0r?SCzu$9X+Hvz4A#KOj%eOjUg_)^kmHOR* z1`3r%1NNDUgv3N)up5mIjhZ)>YP>$qw8+_m~#CmCO(2yCKyGw00000NkvXXu0mjf DL5fvw literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/basket_edit.png b/base/resources.pk3dir/gfx/icon16/basket_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..8138bbdf05086e7f8629fddd2620ef1afc403cb9 GIT binary patch literal 811 zcmV+`1JwM9P)=;R!)R*{6v_K`G+ksyda;zeC!nj>s}-s|U^l!%WrJook$c!=9!O}3 zv>H?DEKFO32*|HtRC0n&3I>BxqFEC}vnIS=?@Uim&vqmdL6g$B>G%7g)9FCupnYBx zTX2_RY0M6+e#Y0am*^Fx#}b`x42Q!Y0PuJ`RG-fWyWQ?{xm?g{wYRKRE4&8kvoGUS zh<&nR!6U*(unphl`Vna1ZIg&9#|8%n(cRsh;&eKbZ8qB(qtSR+qtTER3dR26w(EBm z$1AtCHu|yg;VvSBg_u;bG2E1kM-K`-JNI_G-OB_3L^WzhM+ekub&lC=Mwcq9W-(Zf zt*8&{GYmxMX;_)yV@66@(zn#3prD{^2jFlx+AS7Kie9fzR;g5Exm7*;pR0z_f(2)+xA}nxCH^<8U~sI{=f(L?r-FDwR}&!2q4;MqQ}A1X~-uh|aRH zIiG_i;w0}SS7LQSKJxPNa@lP5EQ7%~`1AQ%TU+DJ&CSWO;Jj#5Vttl| zNT3W;VoJnRoqmqT13T>+UF4@7Gi p$Kzd3(&DbClpb5@$)kJy#_u2g$edtF$hQCh002ovPDHLkV1k`ddgA~9 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/basket_error.png b/base/resources.pk3dir/gfx/icon16/basket_error.png new file mode 100644 index 0000000000000000000000000000000000000000..3978b2923ad6c7b4a5dc47ef27f8476f8a707d76 GIT binary patch literal 794 zcmV+#1LgdQP)sl!)1JQyAh{Jt+NLd0LFDr+7@6S2w{R5lYZfG1_t~4R>k90x6E9S7 zX$X7_K$Rek?eFet(@HT{eqG8Wp|g&hS~UZ&*Ly>fqz(+oX0tqo(QGy|Hv8*zTVs_X z5D0*=JOxa`MU>Si*q6hOWG0jOl1`@qF~TBI(&==~DAtUL^E}TpPN#FEzEZ33`~8On z6$gdlt9gT|la2ZAc?CgGi=ueRWHL3Qh>=CoKrk4DL?WTbggqLKwj=IaSXkJMjnAv; zlj|k5UHZbxEl|dXYV_>LA*>Jke7?Mc53I#vnL%JXJpcC6G(J1H<-n zjGQc9WQZ6-0r&Dvv|6oMw4_0DotlKdw+OD`hK`d>O1TS2X71OS$w4NxL--R5&+J39 zr!T*#UA_lMpP$`B)8H_!e#x4RxoCaNEEi|Yjem>%l4acjK=DVE=fyuAA=Ktrvw>RP5<&7h*Ts$HjZ`yyrZ>m-jgw3IO##wdLW` z(o#+$k;wfg0RQ=7U59z*^NUbyP3m1)yUQ#z{4s!-E889O5ZY&<@V!HK;5{Nm3*dMKVciQ>hdP0O4?$8;ivd2n1rGPzZLrz1rvV!DuvA@tHE*8a@HNK?ku| zT$2F{g~E>%nQ}NDk7H_Ts$gPbg5~%7OWbbvKAX+PF`LbK27{q^U|?W(<8aAWv7d)( zeG%@6>)8YXfj}^t-D7fc@)H4oOydTFL0GNU>jLXp@R`zdGkp^ErsHXmrwY!52JNmZ zIH%s5Hql13w6t_&0b^rh<0B&@1x}}vWwBT|CX*?@jVXn9Q3v;eHfyve`q3Y12OaCf zZEFQiJ!XN|%B{=-JRT310KhN|*X43Sr_)_)B>QH}s-OV!@iz3nY(kH}9+J^!=%=Nq zHJ?FYH}!MlIcS>xLBe8bwb~+;O0}oPcm$4kKdiG#(9u3Td-H@qS}`~+L6h|Y3cGT? z@9(6FHvl9okg%XsDj}1}aCMN4i<5$NH}`)5qM)n=Nef1O00000NkvXX Hu0mjfkRfIr literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/basket_put.png b/base/resources.pk3dir/gfx/icon16/basket_put.png new file mode 100644 index 0000000000000000000000000000000000000000..be62faaaab2773a6e951c3b54eec1303214cf4c2 GIT binary patch literal 733 zcmV<30wVp1P)k4ls z?I!B3WVC@<#F`aNER-!jYPQ1Y^<$s!$F}~@D5-FE;K%=co^zga&hzoIN~J=Z*|kUe zD`H8cmBJe3ob|WC?;=|ty?Cj+a{UZ=3Z(t?V;sNiq;AO_1TYM zPddZX*@@zRx3KW}R`+afoaTiIvgn)1YHXwU@^eb98>x5uee1xLyIor*7_=9!tCxmo zGWUdLeuQX7ct)>N$@RwUDYCLW_1nuA{yOaG>FGO)qU-}C%d!TvdpsWYaBN%*+0JNH zf|D+{4AaYaqHv^tZ+#>Z$xD*-Nfbqbepg|kVzb#?Nan)CRgFf&qS5H9jvZ$0iPe#l zrwunLkw_eGv+C-@;qZuFuh$ie#UZED=|Ylr7K_C?7-JuExm*hp2*3@}a5nNvz=7{Y zXfyO1vw!#k)K`T>5Q$z;wq}JHQfXLgiiH zVjvLc+jxmspaum5)2}Pq0E;%@*NsD`QmOQ~`VMOS&Rdz^@7Hh*27}U1CMl+92*+qN P00000NkvXXu0mjfPQ5eU+*>qNCZ^P_vEK24YDO;&<-m{sob!F>yPR`|({-J4jrtym zb5yFCuiu36=jXm0q-};_JA=2{t{u0uQ%li_n(AKh*?$G-9;wrPrdET;9w3i&jQqQr zj#l+p@8$C4wzhC%Z zqu52Y`la^M(hc%c=h@v3p>Swu=&s3R5|YW}^@@rL4}z3&p-^ZK$8jHGu~;zz$Y38> zf^jFy1l;(JK#QQCp)RmyG#Zy=S$<^j`F!E^_4V(l;1e8LU>HXRzaR*c(16)&ehqDg zzJ)ztv)Pz7y4`Np!i$Y}Fo=Q4c^Fs)<m=o#NJYL~O_d2{_ZQE6RdRS=e>s&?%ixKg{_r{LAR*=-`}H~;_u literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/bell.png b/base/resources.pk3dir/gfx/icon16/bell.png new file mode 100644 index 0000000000000000000000000000000000000000..6e0015df4f737ded7e7e14b546616e704f023226 GIT binary patch literal 789 zcmV+w1M2*VP)w3Y+732PG_{dW-vWnGW?ek+eegcN?|t9z2?7xGKN@MGRD*J^ z&rlky@ZUE!D5>oxB^64H+e}Jso>dhAcXJ|I^4Pu&0hSi(IWgLX71SJg^}9{IANt4a z6@3vO@*Gyvx&UJ2j;g6eXHOcITv{wUTQS>}4p&n=2Fk;r%w^@S*8a(S*4l9Z?xB2q zbEz@ceIA}S32-WSa5Toip*ae*h-LZ>K#V(y+NX@kSg_V%$^H^^#w5(VjmNa^Al#Zr zxKskTv?tM3%<%;PqbiC^j8kOR6?gv~_-2jxYPk=$UI?e|FeaO0Fjl)4b{QYeM$$#= z33NONUJd|;c@3 zEdc1N;!Mt4u3_FH!uuLNdh0_mSQm{kBBv%A#u5&?pX`FYmIHU&F-*wfPx9%`;Lgug8DbunAt zBaI+kWJ7UF0I#(WUwSj4$>*c9h=G}AiU3$-A0$Ax*`Bq(7C5v$WSb3D;V`_ofN@<0 zyyGH_s4k);Wh-=dcVI!ug{|Qbq&Jv@e+2kN0@9!>-iNlrSST`i(3d5k^wJhQO4^KW zF%1@J6soS$C)Ne{CC_FFV2Y&a z4Co4YFjq&xTp5X`tPqr@&_w?P@T)qFu}N};o>QJmcZySJ(R-Md ToJi+(00000NkvXXu0mjf*@atu literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/bell_add.png b/base/resources.pk3dir/gfx/icon16/bell_add.png new file mode 100644 index 0000000000000000000000000000000000000000..7db01d627922c6ef45c8cb85020fb230d1f9bcb2 GIT binary patch literal 816 zcmV-01JC@4P)r0JK8p ziZcp8(3p9#IermhN~gTGd#xC^6fa0Bd6~45i+Xr!rFioZZMAX=*zNTYoNo zSQVJ-x`3HCA+X3en6CH7bW11{>5Rd30Lti0sdY+s5#LPJSTt8+PInq#-v;Be<`8Tx z`(Y)yu&Tq+S-@I$07giHO&O=CyRO)J?_+sZhwsKr*tB7=XpUgA$seOtUNB2MVX3E5 zC{Lj+%YDfK7?85nHvM@lO_#$yo(%h7G!}Z#!TKr~BQ-wgf5yRw5&|aip4DqiDNdq3 zg)!j(=qp&0^TwN)H>TtL3s3aac%ZM^52KVUEq>4yvCvhx8|Eq&Y^oC&mjt0Y$xY$_ zbUbu_JWK{*W{3|%T?ELq0BDMjL7m6MM+p}*N^j_knRr|^N|CNH7r>NfClLebD$h=%@R&`Y3>flz&e1}v0LKysfjbUpTVbhVK{ty z7xGlskfY+Qnsb!AjT8JWaiUwgIKdT~JPxw52}BC^B42fVwKKib^_n->NYCS4x0J`a u@JpjzEWDVV_P{vjpLA?W^OPRYXMO`Z^tmZ;1l9Zi00003@?;{2!fhnpdDVjACjRc9&&}_7G!fzd+)6QD z^js-e&7gSabE~uFe+JIvM-+_c8dsFa%V9nCP%1n`ZFBWufExnUQvL%p9uS{|rz9GS zB=!3FwxC?C>qzOkK(&;gR>D#|QwS&aKZYg&_8%qOwV#PcJgvI6HTU@27vKC>pjyg5 zVT6Z2i;vBcNZ*ECKSi+9#%s3_ElPTFnA)FPPXm7ks-=7e_$ZRT{odHfEPaN9effQq zW20OLJrYKI8_Xd_qvq6Z&b%<6pVke&3Vg;>lTT^MiAQiZzQDS&h_Y?`o`b#JCDbqU zn}P&_Wh=D@_>P=RPan#}M~@IVD|pQl=-xKsxpX!xyd4*>=V2x_FicdS*xpgCJ;1Z% zU}!Lnv(sSt+amq_iav=F0^*52YHJpT2!?3rgE!Obba7nyeizW~Yihn(`4!)H85o$N zUWwCe4REQpPWM`msav9$x?;29@%x8Av2x-&5=)J{%lDhF0%#(_;(G_aiDgoUr|vky zm#2ypjy{XM)#itCk(AM4$T#V(k1%u3lZ0}&VlS0Bx3~~oU9P;S?N)i=_<{5BeaRWr z45Qhb7|$iBpR4fsr$r84b-3&3aU!c{q46~&lC;e%Kb99S?!EE8W7Yhbx!mc&#PaNg z&CC3;Fd1+0$2@+uAOdTadTmC3hI^7`n$7^#kr*Hlal`IvegYu)Ek%Lu%lyrJD_ z&L6*!HC#uIc^=OXI}#n(XlWr&!hsCQtw$vWGj$RSg4MP#$JT9~>*(5N&#&*-6OANOx%eB+tcDd0+ph(OOzXSet)ue=n#fRxPKJ!7q4Td0;96nICJD&_1!IjO3|5$ zB?m6qJ0|JPj^WOKMAWJi)R#~rO?G5}x#h+&;9;Orbn?K3RQBnYtlT7BF%S3ddx+;E zzK5AgqM-}%ezvFMqYrZN->*2k%otxsA%lG*M~%!Q2k}?GqPcJtab3bqk4-Ou*)vQk zDnq0+U6BWX8G8DGJ+wPN{OsFCkL?rG-p6duqJhu-)h6q87fEEXA3KI;W|2r(Z^=@p zLD1B~ww^3r>mIkSO_N9nU7BVaVE1;h?4`+#PGRTwuyWHvyat}HGo1$RhFq!L`k65F z>Fyq7{+3N`shc}8&i3)+G+Q8Ie$oM+J6S$aE8V+xclHZ*?tYS> z-Dcvo1MJ!NI;-mz1BEwXbC#J47fEMaq9}$_7)f>jfEP|x_O4XdO21tFlDt!(R$fHK zCp)|stFMiCRZt{<8WT42~V9+p44CDi|?-{ImoJvRNYc z_%M+doc!kO*b~N9Yn(YhF+cvs#i5va2MyPNzyFxTQVvTuuT#2w_R^MH2t7YJ`|*^k rqKHUbBZ;dBDypdXDyoQ}s)K(4xVc{-Vpqm500000NkvXXu0mjfWm$>@ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/bell_go.png b/base/resources.pk3dir/gfx/icon16/bell_go.png new file mode 100644 index 0000000000000000000000000000000000000000..b89bb343458ea62488d810fd38a052c6a0572b30 GIT binary patch literal 836 zcmV-K1H1f*P)Yz&dqT~oxC<;gIOR^S%DIiX_Scdk}vgKP!L@}D(FJ>QuL4&2|W}( z1Vs^zWETnXMvxi>si`B5la80k%W*t&&OT@Fwt_;DMf+txto41Yz1Cg=V+{Xu`h8v> zQCXQ3(tSn82CHKJ3B2^WDBuzWj8eu<8AZ#!B%=d?AA|cB<9`+S8@=}-U@y~PBb1pf zCc7Byn_{4l)IMat;ah%nGRC*N{eAKxG+Pl#6B;5Ff`7 z7sJ4G21%xLMW89{o-?n|ZA~eMuJnV1?m{H9U_`}SSOSTtAW?!^vmFtQ;C!r(*$5q9 z5fF*x$0s_WM82c9!-u#yidbewJP%rJu?UPwFz~+;HLA#PuE*JtE>vi&b6FtD^Ryw< z^97owA|W9c!5%9@;|aK}#pCLvfCqLPYAw8Z_B`aL6(KX(i-+!LWyuYPc~KxN{=}AB zo_32nX?yP0ax~TXPTPsK_n%npu_(Toq=W=)l|pQ6pBy! zcf7ss=~I+f>)hUaga*gJgG=ymnD>Qh&?o`X3FZ_Dg_*^eCkx_-q1Ldt{Fc%hzjtD2 z`gvrg7X#gGTo8rEN0VyJLYg%jZkvaX)&!R&9bF@BXd7&uTu`xD_>9nsz6z^tMQy zJJHemUXnn!aJX-!iL0IZ6WIn;VKs!{_|5d7OJSl=IGs@P;?7*la?VfOO=or#Hn2Yc O0000JYm9`uEdlL{An(2adpq%j49-vJ2@kpJ&w0~X z3{(g04JcXAl?1l_6F>%;(hO3o>(VB1=WP!5Z-oJ&@XM4`W zJzj|)E)zV~Ygl;~2d6$1j+SURI^toH2ipDskiny*-Y!`(urb?+?S&WcSh!g2=isaP z0^A*^;WD0rt2-HkRSd5WFl{85WN?YR>z;c=3h$Z)-|eMv4_t!N%*J9{G-m30Wu6VnZYn z6|&jvLo}tYDrjJ+Ari}z5)|KLL#0x|;c&oix1+bW7u636p;ibnX&a+^{r&y4hsWbp z`d*={JZQ338Uaa>7}k*ylu5IY%1ePzD1=(AMsaa5UGq}7$jHbrQILXyf;GQCka;C^ zs#Gqc0dI;}NQ{q#*=&Z@YDHgPA9Ok$;yLU+KA(S(0?6g^Ek8h5SXgdO_N@&Ha7UPo zgai(fl9G^?mPU)Jr?}raY9_4?qyaf!NsCa4whoB`YiITV7t?R(_snS9ar!M}D2<$rt79lD%ze cjq*_5UuZ|Dxxf{wWB>pF07*qoM6N<$f_V&p-v9sr literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/bin.png b/base/resources.pk3dir/gfx/icon16/bin.png new file mode 100644 index 0000000000000000000000000000000000000000..ebad933c8b3729a9b27dc34c5a111600b8d46fdb GIT binary patch literal 476 zcmV<20VDp2P)!P6q=I0_iwCeRuEs-nY*ui2wlBo{da&-rimXk_dpOx8l9Y2eXq^TiLre{gv0N zh@vQpp3E(_zQv8WAB*@mevb>S`MD?sAf3NIKIx==eZ#Jr9#7|~0H2e>)YKJ;10yn{ zb~SBXr^1(^@_cc&7(P~SnNU?q95~@CRVtL1isxZE)U%{&!=XelB6GnODxd1btErjO zj_6poZCs)d1RVpU;qKVX8HX|rHyyQURHCLW%8}-eFWR-IYhR*iQ-E&#nFI_$K^_5DwQb0QR_*>mIH#Cqd99N2l)Z|DPKCCbQ(9lp- zvu47Wa~kew3p-R8Jp8%booy=RR$@JQDF}+Z*eRMM5iCB+Uxaqp3-6bf0D%9C#5QQ<|d}62BjvZR2H60wE-&n>*?YcA|c6o&|A+rkb&Vsas2(@ zRZChzd<-rL%s+C)K`AUj&@4exERnTGr7g|ufjFlYo2X-lQc?WBS5|%h$H~-pP=>{CWcO1^&sC zas{(rHNEeVX?R|+D*2koKAT-1TVxuXF7Gt2pCrhe%W27Qah0e`>%4W-qEi^2ys8L$ zkzFy>C52%M!-~#H9Xt(|Evme3 znsTM3@O9jy7lMk63GZ(u8Hac+{l2Nv{)WYyc2KzeV81veQkLz}aZs=_c)I$ztaD0e F0sv?9ij)8V literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/bin_empty.png b/base/resources.pk3dir/gfx/icon16/bin_empty.png new file mode 100644 index 0000000000000000000000000000000000000000..375b8bf6a09803b8fcee625fc5f38a949b5a1439 GIT binary patch literal 475 zcmV<10VMv3P)rCP_(<-a*jb_Hyre&wGyNNooK906+!+3lsI|p?tm?Ex#0xHV4K10Z9#DVK`pc ze*7w-lmAYiqVQ^K;s*qy{gNXl3K__@vT?o(V&K zcsjVVE#qaQIuQ57;gih|+H#dz(D2^m2pQGkc(XiPHv7qxcY;izAvom~vS-bB@7UaK zL)NX}h(uIcx2`~1o@>ob`KK>8W8A9k5@R}Q0cp50?UzkmTM})nYN>`oEg%iMGT-&} z_59V;^#>H9fVBA5b5zGCT|Ep8R4PHGL|Q!gtm(MZas<&1m0H7?fb{C)mF3rRxlv=@ zIH+Z>+^mjrjf~>_+vV_K8L+b&88i{a`h`7P#Ww_cAT-3>7iG?d zKQ=FfJTtdc)9<~|e5oamr>PvpaLsiMK% z)`3JKfz0M{+kjr+tJMf=)!zW)RDC`lVzC%#5o2Rx@Or(N z+pwWr_G0Cy#KMLfiChPqPN$_Y0QGvkUkCxe-;Z!O3?8>yEmSHM!)YC#@*XrA4QQHX z0BF760&r5HP@qa>L#*q%0boI`Rx<$XRMi0R97hX46Bz=Guz(YJks&PLZ=UBdyUk`p zsZ`>ej0K>|afib(q9}^d4OeFfM;4ipp)QvTJ3Bi(j$5}tCq9+UX8HLVTi_P?ApdRO zZnqn4=W;oEbYjW^%*@QBNDxgXlO=9ZRaFCIR%heN3`nQbC8{1JXzH(jfvvZ<_c95_ zgTY{*$Kx^fYu?80?k<*>m$`D3z?1*|Or`|_fk8U72%SNQDjC;Ho*|D@?i7hr`}2PR X#`)v2r!)w#00000NkvXXu0mjfQIK%^ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/book.png b/base/resources.pk3dir/gfx/icon16/book.png new file mode 100644 index 0000000000000000000000000000000000000000..b0f4dd7928cc5714e002fd2a6e8f2faac0073f00 GIT binary patch literal 593 zcmV-X0l6k>CGhc0FIuigU9U^L+D`6bSr zIEp(+L4eIgaZT(|{B!*DbrTYc1t0J9*MLJm+n zOEVloE20S^g6s|1rvjjuW1W$TV;&TbK2|slm=91)Q{X{Kg;c!Saglq7xo8`(>{A}G zw@`8gScq(adr(4@;>^%e<~7+uNMv&?8L0#%0yj~@DW&fPImKeyFHkRKuNERO3(SOB z?S)niZbFEN`0<|w+LjBKR#DU7F3d&rQGGY&Y)Fv0w002i=Jm_>x9jBX>wg3XCKK`E f>xbvJ_5i;DeEQXvyE?}U00000NkvXXu0mjfKqCEw literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/book_add.png b/base/resources.pk3dir/gfx/icon16/book_add.png new file mode 100644 index 0000000000000000000000000000000000000000..e2f084727408f27356022964c059b02017988b05 GIT binary patch literal 714 zcmV;*0yX`KP)>I+w#Eg*+A?cQ*gTsOTO&elT=?-PprnusH^iNrUAVMeNReFOLbFcMel&QL3~P_-NYJIZZM z$*ztjRyCBdoPe6gbXRyJOBUy07*qoM6N<$f)d9;DgXcg literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/book_addresses.png b/base/resources.pk3dir/gfx/icon16/book_addresses.png new file mode 100644 index 0000000000000000000000000000000000000000..b73419ba82098bbdca1989d31fa798756c987524 GIT binary patch literal 770 zcmV+d1O5DoP)LHt}U(fC{;>Yum{xmD^Y@B5nN0h99fKm3?`0_{sl~q#>Lf`Xq^mk zkPrtoHo*|Z3nt2x}Jy`Dy+VWv$$5Q(e+JC7mM8^t0(iL(m}3r?Oq>CBlk z+U+S25g-Hs)ayudKxvr*V(ri6%46oq;@1yc0P zA3d#Jwv=Vd%^Q~uhdUw?5#qmljMYF15n(hM*?Rc9vGHS$KYP}#o8KGsA85A5J$?L5 z*MC`7uV)9h3*UUa-*A}z_>9dmBBYe0l)#gR7WI4g9iBg>J=3wbH*kCHJ4ZXOSYQ27 zDru6(55yX)S@&n6~krBum)TC;$e8swaf zMkA1;lB^Q1DT^mw z_wd1AvaF1rQ^f`GXt>pMc(a6@v#P4V>fhgb;ib1-`{@%;>^~y%NUa>Var+02W?K%X zYERjjxIaDC&rwE%l#-mYDhz}(!NW^0=wBZMH5C_+RAIVF!K23~z}<>ANUn_?}3M|H~;_u07*qoM6N<$f@;M1& literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/book_delete.png b/base/resources.pk3dir/gfx/icon16/book_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..d9a6340d723dc9b47169f3470c503ae0514c840e GIT binary patch literal 719 zcmV;=0x=?)~1m0FJ8hb!d!Yu0W+yAtWhc z*}ae_E)-c*SA)6F0RT)5(LjlN(j#U@j*&Uo8i!f8Sj^uk+*2o^bAxTO*OM%hKM2Jh&W@l4NSi2qVCCAlJZX` zf$_0Cn&-##49Ml!zH<{EMW{NWj#cyMmJ_^t)kS0dJmP$T@nKe*hK>*g-q220wjnJ98}m)EabiEnKG)?OAx~Z6__u- zVj)yS6Ro_77yvtqg*D!%oomRiETS<1QHiTcTzy$%hRmV_J9dA|I{;Ld6g!%^b#IKh zx!0%&08&+!164spaZYg}SWy-N!{w`k?*k~# z2@}&5Qht&k2ryxUl{jyyBauu|NDp(e`xokVbuxUmN4;QjUv&nE6Rb0YVaT3s?Xmn= z9jeNmyM1g+KWB0A8*;5%m@lno^yj`4H3h~A&RDGTxiI(_p|Mz}I4iWI|6tFiG7Y&M z%#Qy}%8U4*VFlR_^SK(pS|KuqNI?BGUNQ;3vO4vEy&Gp~T-!r9b%|8QV`69&6GShA zh5x#%L&R8z4J@H?SSJ`KtmHmlca+Gr^%6|}grBk`v&{svBZ&1s?>gH5*sm#Yf(Z?w zaRkP(ql@^{3+~fO!2DTpU9|G{-Zoxz`ps{k7FY?b=-ti^T z^FHcQN?2)T>h^tp82OB``E>0W{i#(7v{#if0`DuhzOg%h>5b$bt6{W$4Tw8RQ z7g6@TMv4s+ISM*J;iEG=x^#@kcYY(C-%NRCikr!UWHL)p#t@OG?O^3)fwPCHG3Skh|?C7Z~pX@)~r^*3ES@GmJTU(dWwV{QH rsGh5(PUcLu_A^ng|9SQ51*2b9!67)iy>GqcMEC5#P* zVFs9y6`M&Fk9XyF_s^Z^0?3gy95h(oU+9Rwek)@(Jp>s{F@^E+FQ%NKmRrJ~$N;dZ zztA3S8EB`YwI9m}sA;xUv+XTSb=1}7*tp{mvjCXQ>+kF2=F>NnN|Tr>06MM03{zu# zVv@wA{2PBP5anue^sMNld(nJEz)Vp!L<~_Ss4-d^N|?B&1tzY4r4;sZfq&fj~5 z^MN2nED771uduXd3#H;C%<{7U@iZU=CH0cGQ=aLOHwhq#oj?vyY zUI_p`2q6hLFC;-oypWeK^fF3Aa}zRgjkbY(Y;Ai@Ra{AdDBk%D;05o6f<2_IZ#N{* z89R4@`lczC)qiAlo2zWWrx_p($^t2}a#2LXyh+r(15@PZ6S_7ZV^^WX*s1jmGXOOs z4MK1M=atl_td`p}b*w@sUtl`L&~PuBex|mz$l%6df=iFix&skIQo(tl+mF)QGe}*- zcP#vXsETJ-i-4j@k(Onhi1UXZjI1ckJR@<;nsozM6fyMaE-i)A5WgpGYyph5`*+T` zuF5Z^YwPia#p@#{rvZ0v-55QP{XAo6d6~y&_F!t5>Z}@Rkk}+e6*F7>8&yNBiO-YD QcK`qY07*qoM6N<$g5Ksv>;M1& literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/book_go.png b/base/resources.pk3dir/gfx/icon16/book_go.png new file mode 100644 index 0000000000000000000000000000000000000000..cd4e1964c4fc6288ffe2a52bdb8279b38f4694e2 GIT binary patch literal 745 zcmVmRp;U2rehpEP*hRW`OfcGbt-Xp_8t4T*WE8WOyF#D z9CyH-V)EHx8i{%B{osXDs{u+B2M#;@S?%dgK7Oj<-b{i5X1Kv*?Hkj%V_sUtOcVgv zS?%dc{_g9d`;RJK5HPo*suk6jE}qZ)wi4U-AK@ne?n|n@E4lgfEfW(B+zbF~s&L26 znVf2n<$<{|V}Yd9T4LRXm8|WopbGAWnWO5c8Dh?K7P)j~;CBE=)fo9WMQd6n%Q9jf z5G(eD7E0w-Iu^{s+AZ#%iNfS8S&qrg`>Zu-5laS}D!75JLeFb21I68zZ0J5KRz^M2$@4U)k8T zgL-VFkKYe{E;Sn_h$6X=M%8P7)_@ZjChry%T^y#rN8 zgBBLdXn4-~hi3^E$Rx0)qlc}l_wZz7h&wL^HBZ^*MH_f b^BKPbr%B>ylaEW500000NkvXXu0mjfu(4I; literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/book_key.png b/base/resources.pk3dir/gfx/icon16/book_key.png new file mode 100644 index 0000000000000000000000000000000000000000..d8e23ec9329a160181b5dd14079e95d769e681ff GIT binary patch literal 779 zcmV+m1N8ifP)JNR5;6R zlTA!qRTRg6@6BT%D1r!D5(}0f7+??^@jDV1BqUmldz&sajk_i;>)xf?E={XR8-;~U zTChZ*#`+PPnvkG?B9K6gb;1k-Grarmz2~@iGbqYQZccJ@@9+Ho=bjs=Diaqz9#GZK z6$&UXDT*qfN}BX=iMLp@yMFu12i*V>>4EbKPv!bMgZqE&qFTEIDNIm-;%=D(qliYQ zs74BaS9AR*gV%;m(%F$iQv#xrR+Y4RdrKpY4G}ND`5s3As6Lz<=wkZrZxjj@R0II2 zsZd2lDV8e4CgI;vwLlPMBc2@WqUW(zya!c5MDbqnA~;bFV#{Zf3&#Nz?}g3#C9+{1 zaU5e!f|GRLks+$f()K_-qIwJf5HC1yF~;!Lb3Lj2R2{0y<@sND;$V`C&#p3ADg0l7 z^@6t!=R-bS_!(mz&MV#tj({OI&ohH1n)~19#3LVZ@5A2l(-&7~4gt;yiM1pG8rBok z)j_C8AoRxbjPfsp$*d@79`#bsiTxjP*D#STEJAbcVmul6xIr zS)!rsabmwk$LMgQD;F;PqreN+Sd8_l9j_!+$e*qiTi77Xx@76B~49=xNSlyLfC}bgym~1@zP4^d{i5l#Ce=?7%Ny2`rHqUMBniA zD`RMKi@@)(c=LdyP$Uq`)<)^=vsc%r4twCe;uD`*5aEU9pBNrJLz2Hl6g9IrmoU5c z248PRkTT2n_t&YFV58fe*<5d*O+HQosR$j002ov JPDHLkV1g02XZ-*G literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/book_link.png b/base/resources.pk3dir/gfx/icon16/book_link.png new file mode 100644 index 0000000000000000000000000000000000000000..dd0820e86d0ae7484a9d1fea509ce168ad44699a GIT binary patch literal 789 zcmV+w1M2*VP)Ibg27S@bI=*bsb;IgkCPuV5Vkc|%HT6t6!`B9|*t zHpjbmR#Y%cB>BZ6G~K|TYq0zotNP0+pjRo1^k6y zQ(zK-ZCXSU!1IwY=-xjmu$Tf4f+)hU{HAV5V3E@>O&HWaHz0u%1Ry{!z_DJC&*o_V zmjEy=8pfOy7Z^<;&>NY@@?}se=09I0f1Ga6p zG?rs_c2-+00f7M84&%w5U zF$P?S$NA+oaJ9O6Q0&X}iyNdtz%UGZB(nkoV~cB?a3#4vc;;xhAxr%76YzLEP+hO? z?&=*KAO<-*-2YJsNtsLr645Ah?T~_PZC=>bAwxEs1zuLUTn1HDfe;f*X#rxIfMnHN zCkx2!77hx9g01U1<+RIcy&ye$%m2*Tg(5LgBW?-F5D%H?w4^?K`MF2rr8R>tbKv2HLCJnr;&f?m);TU^d+FTbf$I2?vz zu_%a}F76$EB-+Qz3WY+@p6JIiy|6tv*_UrkzroC_NREjv$g&J>w;TL^zkno3;B-10 z1jS4szAx;Z4ITI~jtNz zZhT67I+aW`o%x}m4?^&tT}aQ)3kRJY0g-8BG}Y8W4bg1z9Q?8S!u?m3O8F!oWuISO k(%#-l{_i$Awz|&00Xevia);hrMF0Q*07*qoM6N<$f^aM`9RL6T literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/book_open.png b/base/resources.pk3dir/gfx/icon16/book_open.png new file mode 100644 index 0000000000000000000000000000000000000000..7d863f949741ff83fd8373a77c0d95a3d95e441f GIT binary patch literal 622 zcmV-!0+IcRP)YeaZ-G+53gSTz{SPWVdFiPaPX+$~@n)fi9>qgJ zh4fN-QcEhq^wI<|vImjml9)pF*W2zl+qWbTPaSyKyqWKt`DS)j3xa?yVgf%ewhl|m zA$_0x^Rx4E@d&=>uRoSN*Cm&aL#`7&zr0;L(pKMn1G#$ZszFkMC^?B8f`0w&-UD$u zd-(?iK6#!;xZ`>J^A9DGiTfguewDOKwDEKoL}`ZE_M}0=xvsgf$usmJeV$oo28d0#yu!pdgpag$giC zhlKP!CMX3wsPMGgZ5n>Xg+hV--ENofAcH61#0B7Hvl-7Il}g2A6;lfG`FxbX8A>p$ z0P;GW4il9Mr9jO9)xB^Rgy%*CSTdQ6D;kDDnM{U{5Q21FA4#ZM71$_Dba8z<-Y_Na zS@|v#c0PZNDux9AoXD-ZoWP~q)7QrC`Gr3gZ6sTvbKG`S=Qf*6}Nf4;Z7Z{zN!O--ANbYb~sXZM@=W_MPrR;$>|(APVL z9?v<)29FSdeXBlhS+G{-_{fQm(s$|pt3F04wDk%Eai0K>nDfCMZg4J%Tm>-+#q|66 z8(eUXMZynJwbm5eoE>%wcnw@1t#WGynhm$k?XL&soFn!ri`4f$cVy<%2mLsExU->z zZx*xss|zVtj$|^aY{nS+ySuS>yS}Tnbt?kCHpJucS_vZi7oW4eS02jdvmho#X{ij; zASmWb3g!Cg&?GXM48q|syk4&gstfW5ufx~d(b5UV8T>6lg%x6ea*97xpv5pT@eDFq zp-_Nnno3HNxizp%!hp9l*G6j*sWM<7rm?Hgq>7h^v`h)1B=y2@X=W?ZT z$YtMx?9VKI<#P?vWl4;(2C}r%>Gaw&UVVOfffyvn3OyrEa&l~WX&F&m?+<#OqiY~^j9wuSWM=zzA_@B9}<+jo_mWWEvr O0000i3lOYrtSl@<#7b-w zf}j{s!5HvocfT|9z82@(O@vrwU^wRt=bd>tXQpGD!`Kvuv@XEI8~tgUP2L`{+*)U@I@ zrVtr5X14??iAF(=0+k>q)v`Scm$9&=i`*knBsnaUVL1>ti*O1xfzmiD$%Md-h*6M( z@*iB)icu3eU424Ok{kp%Y!1dvp%f0`ac9vcupx^$vU0xuKpJcBvej0UYk%)EV>mIx2hV}QRf#LX^Uh(%`7hZ~|KEf#uQ31s002ovPDHLkV1hgQ{`mj^ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/brick.png b/base/resources.pk3dir/gfx/icon16/brick.png new file mode 100644 index 0000000000000000000000000000000000000000..7851cf34c946e5667221e3478668503eb1cd733f GIT binary patch literal 452 zcmV;#0XzPQP)Pdwe5?6tW?r-ok|b$oDQj8FV%kZPq;(MWOV8?8;<)(iP}>hNMU> z7fbz%jjlr7h8uuoQ~J6}n}@Y@PdTk=)PxO{%7zmL?dchpZX*~n;I{!C>*(8cU;q(~ zAS%Po_@naEU!xidrBXD?;hN|x^%W|Ij)0y*r5vi|?W&Fub(NqJ@z0o=O5P)$DtCMgZgg9MW%rA`w{qe=RC&!sIosTV%x&Y5$*@4M&R5da8Mgu~%CZnwK` zGMSDDw5Qlvxg&vldQFc=`4&GHz1 zqa4aTal{E2d+%?xN~Hpa!-4hnbq>4T&SMfsJx<_sI*km-<#Jq+5R1j&@p!Pjyv#v+ zijkXszmH5N1FBhET(k&GslU0oiDWW~R4T<4NnN^593>J7ghC+%0s-iBy1u~diQR4& zJ3Bkr-rh#3R02C6wzjrT9nn4#iJ(v@z~}REq|<3=wOUcI*=(F(e}5l)dwZx>tK4op z9zX2?sZtZEFc=JSkXwyLBT@r7fhdaD-Q7j2)k3{q=c;tHXf(7dbQ@Zxg0jAF6KM@h+4sC6jtTy+RLI zIeishH}wCE^>ao^1fxHPUa!B*=4)mnI-uq<2Oz|6c+rSn>=*hio4|XDI#$RoWYMPX?k900000 LNkvXXu0mjfahOHG literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/brick_delete.png b/base/resources.pk3dir/gfx/icon16/brick_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..3a8c373482e071726fcf2e8967eb3c762b224cbe GIT binary patch literal 745 zcmVk(*8wLyDN6qc8lhZhzWexdK7n$>DOH&Eb@W1hKn8Q^d@kW41g?RL@Wbg;d>&1>|H z_R!v=L|lNWxBqtA-QC5~(h_2^7>CVfq3AG<**(V(o?;pYD#p|9T1vg`zE3EEYGZ7mG!H z3=*MUPy!O*&Ws$JzJ?#pH|Ql-(faThp{Xl)KQ;bEU}HMXF2|(VY|c=3_xAQstJQcj zNr2+J?w!YXM#j5wVCD=kJBr$?>u}u~${$}zlgTt}G#X#B*&b|eZgLS4qXw?sl%p51 z|1;Ku7bEOAL%kFKf?lt`%;sxhBkIxJ@OV786E00000NkvXXu0mjf_hDCw literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/brick_edit.png b/base/resources.pk3dir/gfx/icon16/brick_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..eb06df3bb3e38de2faf51d80a05e8254d13fb18e GIT binary patch literal 775 zcmV+i1Ni)jP)^9OfoSNCh6N{UH*G>^7ov@7G7j2))Sp-vPxR_~|#}oBaGXXEK?XK|Y^H zHk(B1f~_(T2#W< zvaL<2kX^Wk+SW9-V%M=b+k-`2ClPnyl}cXV$lX>%QAD9oKqix6;&?ocXf%qjM~iIW z4r(PA#H9|DR@zYr^SQ^mz+r?4uyTP%4!Uj$G3|@^f^JjEqDb4hL3OR}pcKA@uPUsqI85-ih+cW#mYc zi0T}yV>}fm2znF>#s1x2Qlrr{snu#3KhP}(-}k}y;R(|2Hi+?dY|h`tqN){Y<$y?p zaw0sq=UXrho&gF8gkM~M(ASI^Qdy9lgzj1YCn7%n-^X;n>!?(5DN%7hg_ zql4Wy8ok7Z25lz}lpb~*ktPRPq%ZQ*4qNZB!+VJ-egn1}Am_E)CmFH^{)}n~c zK%gbmsn_!1fEEZw6+o5S1JRT2pT}L{dCN-wn+1Y@JEnE)< zgQ(SNU~FK;u)4a6P$;y=E9MQXRx28f2FE&`PLxWeD7KYm7P(xG6eL6jzFa62ZpC7;FUe$*GgI4yjV!E^2Ak_Q^sTS#j*M|* z9><68Ld(BsZ2T;YumYEaZ4biXu$#^Au(;hF@H?HwXYiiB0NI>?t``3GQZPe0*pFgX zL?ID=aCT&2RA_xnV`F2dJo<-lu=~V7`$>hd&M~Pf7NQyShk77L4nVnx_fPJx8M=O6 z*zYyYJsK?ZUYqbqVjf1bOg-AQD?(BND5jJ6{Bks6!ak$9rOJzsLz{-qdQFDzgt3#s cjW*i<0Fgc1D3~yzp{gHSP{di*#8D&?(h#;bi2r7yUe@M_9Z^R^1th67Ma+}U=ey(q{ z%~>)Q;cRVlbJ5&n%2W)U;$S+(K9zyBt*3JiDKhoI1BdsV_j#W8ea|5PNIG0D*E5U7 z66xyd`pdxfEVk3#Z2_~{oMA8+{vd6!m|m|xvLnHN#V}P%QJ}ZC7h_{%NTpIpCX*N) z9py20#_q7Y8;&>uWnbT_HZwDW?(S{`gFz0H$;4x6j@CIrPfw4Q0-;cdD>8V!URbSG z=yW;`wr4TsCXq;BWMl*^N3B-t2~|o=OiaM<_ahJpa7Ct`zBU{U4GqERbi!`8L#0wB z2(>4zt*v2UVF6Q9Q<$Ef2CWa1larf{*nVJO0ORB1u-R-J!^6X9Z*P}~(P-oZD=RBl zUS7uR>@2tI^Z7P=z*NiL=b=!07GJ;F;BYv&+qSkgi8YWDNRou5r6t5-F+?H}uF6Vt zyWL!|xHA_|Ew^z?c?$jZJ}#hCDkVZ^`#Thr?l%iM7ujJ_6Bn65+CbO^3N2U=TO*NG^KHr9~2xj9}2BVoNL)#c(-Kn}D29Z&q=YesW_ z1q5#+N<j%go#9EE}){AAsopP$F#;vyc>dRg+DzH&5tDMkI~BGgzO zpw?OprK=8iJM(bj2}y1~Nv&3!q0wmS>1=;_JRaOpord8@GsN$&Aq+M`<9R_z9zo%% zMUi*~S=A(Vw36g(`wJZ%9oclg;tfR>uC^RQep3c6y*z+>+KZ4oYfzw*A+wr94_A^i zJAS4O&<@KK3WZ%Rm%C}Ru4UKliQgCUky%9|H2LJNzi~HE%kkq?dvUOmWNnTA1HB~u UMVP_&o&W#<07*qoM6N<$f>=0SnE(I) literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/brick_link.png b/base/resources.pk3dir/gfx/icon16/brick_link.png new file mode 100644 index 0000000000000000000000000000000000000000..9ebf013a23a56653655a736a7e149deb7365ea03 GIT binary patch literal 764 zcmV&SR3v>A``^efOSo-hEdApp;^Jd;9y!%1UfzX6Bh- z%-mbG|0Na{7Ruai_Y+DEb1s+b!*9k%Q!whMxjtZKA*?o;i1g&jy0@( zaU=-@d-h+o%gal6JRXEXA&L3`d2 z%jIxzZ~*p9O-;EJp_Ds0If38rM<5W8ic~K>FOK&2_p!CLg^i63OioVb6k$)zWHLx3 z5;!|M!}<9+#QSi1dRlbEcxPt^;cysUuU8@%3}RwpLRIGG<|IKnoyP6$Eh3SKw7a*r zSDXP=IYc&YZf;7@?fCe($^l9ORaJ3wbAx0uiC8QqRr$2t-Cfy8%XCI3B%pxJW>XdM zw~zPt_s}#A@pxQ5Ly)4szaMtH9lgE1SXx@b+S(fW`ub$fYPE8J7#bSNDzme*Ub07{ zQKV8SjEs!%0@v5ql8ggm!@$6Rbi^E8vBqpRM-}l+@5OSMrl+TWj*gC^qoV@>u{fQb zov5v?g~?>X@bEC&+uLPaQ&Ypn-y~^mZA}+f(&2EFH8eE%dU|@ENpN*_1-)L6_4Rc* zFuq@`IjX9vp1QiaK9ZojyZhnQURP99d=u;%37VRkpwsD4U0sd3x;hEQB&e^i|3QN0 z=H|Os1fRqaw!?#igLmS4HE!G3*ce(`TF}wd|HNMlZ|>D)M67h? zOIjz3DJbk0=97q(mSBd~-ilc0Oupt^z$#N6O&at_s8u-PL@9M^gQuq(+UH^IB$&*DHP!HzH+vkEzC?S52tN1$mKhziPkOR=y$ zhl#aO1Xly_M?EkN>tM6E5T&Ht4dh{0oQr6Q1b3J=sM^ACOsvD=TSP81#0oTC1v|Df zgpp-GhL(KrE_8t&(jeFR1W%(osQ12tvSpHp_}~HR_8G{VUO;FILQv(P-b)es=)ZlJM#c>{Wx-rgY3D#Ol9rJl39A<60Xo5cneo(9g5a4q>ayzV-7%Ue2}0_ z&TIets{Cl`n(nefrZ+9F8|N&Kp}^StU2b+&pVj;XvgEdBL3Wlp00000NkvXXu0mjf DwZ3{L literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/briefcase.png b/base/resources.pk3dir/gfx/icon16/briefcase.png new file mode 100644 index 0000000000000000000000000000000000000000..05c564912953467ae888192196aeca2f6db0a406 GIT binary patch literal 793 zcmV+!1LpjRP)wCLzo!u5vjB%3bO!v(<`_0eVUfez^@RtZWvFJys zmGdnDZpkw!t9(+21YEn-ihl~B1qBIC$}CuB14>X1 zU~*Un>6SGZ3Y^8*Q&uVSbD7}5T-49a>2vqn$7#MU@h6((L#!%+= zz%VT|T?$}o@{26(rTuQtd|!BWdNe#6g6~WN^yIoCkxFeKNq#aJCqJG$+l06391?5G z7z>TBP=XG7ma%A``8El+=7!znQNd|bAZ=Jk8A7QPMip0;lwx{5q%cngmVeuX$bNi! zqrCTYUHx_Eeh+kB0G;YJRksPqvt2K8IKWmHFg!IfMBoOAQ&Z@^bIi5NVcR<~{)uxg zY|Ik&{88-~C*A1W?HJn{l#TYlO?I~A&~eSM?)n~-RV0se6$@AD0E_GXV`XdVUHN0T~Y^HSDgA^X!&oW$jpM5h9)mbXmSy~HD zw(w^mE;n9P!K0&YL?RJfsH;OT7({E!J;dI5QDC=imt=c(^T;}l=)l&CLvanNo7&*_ z`=M!?3Q8mr7#tkL(Cg>WG9ie(_q)AF`O?+Z)u!uu3$ZvUnUEhN9WYI^y}!Rdoge!L XLaEPO;P?1x00000NkvXXu0mjfUe98= literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/bug.png b/base/resources.pk3dir/gfx/icon16/bug.png new file mode 100644 index 0000000000000000000000000000000000000000..2d5fb90ec6ee08f53947e0266a87b03f75893446 GIT binary patch literal 774 zcmV+h1Nr=kP) zlgUq0Q544c8(ae&UR$8ps&snq6^bPY3v3xAmMW74Di$h~GCH6E3TaYs2#6A<7K*gC z777H71_Wa;(dfp+g-drPCSWu)#PInZi72LJ;o?i~$-U=y&UbQ89Dul3%3P+Axkzc* zbH-y;QF=hR{qLItf%ci2_&e5wNo0gnVatG?ul6Zw=o$I9Ljfn*ic3`U?>IfEim3g{ zujU&$-hy6wn;w(xme|zJm;lWJxtTFfM)q0`kX!Vu0+d${$}LCddK1<^htTe-fUYL3 zB`SdNsZD>RgvLj1<^@h6_+cDRK2Brcr2~>%$*5S)hyV33PV^teac3%|4lz@8p4?)5 z?t5o^?q+%^%)Yygo~I^U4VR!bTnWuE35hcWrfCDR3q+sxJ79e7Fg`&)RCqLA^2^y^ z0laVfadW90_Fz8Brm|r47sB^u1VgI>kanj)Z4`zMSfHlm8>CwXa$JVM`$2RrmZB-3 zN10m-!;BvH*Br3V8t`DH7m`jf#2upVDXl{5ff18_pzCPK1Zu$$CKKvd8FGeFf)+K<|x33pc7P&S#3GZT4mEw;nr(Ze*F z3&*?-4U-lm*#tber5 z%S_ceqB`b3ko6r~BbvDwdohTvP(3a(pq{x#T$yQsu#OKwEe}KuH^Mh@nxg_(Nw136 zq#a^3xNBke)In+!?qk3%4wB69{pF`Tzg`07*qoM6N<$ Eg55P&8UO$Q literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/bug_add.png b/base/resources.pk3dir/gfx/icon16/bug_add.png new file mode 100644 index 0000000000000000000000000000000000000000..ced78174740958c5e11583682dac645197c09e78 GIT binary patch literal 806 zcmV+>1KIqEP)`=&gfiynuLKNZXG^E&{Pmo=c@q3lv(pO2HUs^S=b~RK*#7&0iej;CY0$=&!}s zlPnn>f-S)ydndO_sP#!8nj+R?CkfAP%XVTzFwO9TP1xb;uc#KsVI@l}Q45e-dhki*R$I z2-9muy!q^gVO|BPfeBvOF`d^nvNfldX*DM?__P--&T^EHL~V~MQP7!$$#>nDeBT4g zbPGxt7D_0BtwZmh)yP<8H860+R0_4Z46G^!QX3=jcx?dt&Gptu5gh%A!qs$BNJZe! zpi8Gf>I6~l|Lc}p0gYR}o2;3W`|jYN2NngaMkxJ}tqVn$`{Hh8DpL5+419Tj?8J72 k;<$%Q*reM26FaHB-E4&O1t4_>`E~n3&`B&r=tE$5)r`S6ZK!@$4#rInBo9QPYpNc{st)6*$_vbLI@z_C zSR{3BXeV`A19V(;ytsw3Aqk31@hC8*Ku}MBq4I>JO^o1Z+S?5Vq|Q}RCwLFoT7iz3 zKW&JH?s*lina@IQh(c1U5D8r|=$vjq-B>l4rJmp?xEZ%d;I{cp5*ikWW)}1>Yf;>v z2$?<-Ntz&t+aqyzyd3flG4734fKf~bT}fN=EO3)<@qlP#SrR&9p&pSUw@ZY?79rxa zCvj)26w=lhq&9_-04mTGG>KIe`^(6|AoZvD_iUbT(t{@o}nj%QdnpkBqzIJEG}nEv_4LaGnGzdzg#fm;?Ah z7NbT4DE0#tPWXHy5JSO~_y4?qW)XdysifnQCKGaPHkf(zb=uaM9&8@pN)BQ~NVRVJ ziM-@Ajl0x&&Gmv4NS)|DvG36p%j5+3oflZQ*>*VN!O+9#d&< zYo8QOm{;z_yR{l;}?JZ=-4>sE5JZmeq?fn90A$P1xW-&(q O0000{*+c^G!iQ-|(6%~LCN zA@Y!iBF(UtNGXJ#^nk?NWwKXJ&2s67_xAd{w%2Q~yc~D9jDi0}CJUZQwS#(;Yq$^K=%m$}|b|DLo2FO9X^c3YQci2rS?u zyuuA3MgEA&(tkZW6u-3e?k=VtilH35gP#*!7%T}^5nj&k8cmWIlP=lzD0`HFh;m1y z)Cc2yX+||%ZhL~ zB+&>;()&0&7=sm6Hx@_zp?d3s`4_Pmm)U%JA~|BZw#2^;)U#8xwQ6U;juxkr+cDJ_ z^+)Un)ucDRKaay`uI>D*bW8K~7SslGE=A1JSj0Hmkm!Z(B@KzY+=m*^F0Uv%p&A$A z$6H^_ttJ`CwNnnKQ~Ng5sM%}bDIL*JLoA*(X5oF0Cl<$jFw-B6*HXdfVF|_f=MFT9 zsx&)begeaC546Yb#^Y;_=twaCFp$bN+Vqe#iNql0@=~`HOFh}>Nfw|gaL+<>j0x+% zpGlMOq_tEj{s))aQXQ9DCAJ-PQO1n_iPiH94U>E_m{*tA00000NkvXXu0mjf-H(&g literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/bug_error.png b/base/resources.pk3dir/gfx/icon16/bug_error.png new file mode 100644 index 0000000000000000000000000000000000000000..c4e8c28096ae0acb84b63a7b51ed824b8d3fc62d GIT binary patch literal 841 zcmV-P1GfB$P)^i)=%W9=Qq(u(JWYNwrWtb6iNXdC)5JnjzyOGW5U1t#% zyK2%*!%WOHwJ5_>j#0e3nAxj$HHlh%xaN88ndiRl`*%GS04$D@XD=U~-8_-$?$PQN z;7+>g|9*3*5Df?z2Ww#`0gpDf&X^KkD?yV>6#uF7_x~E4Hcjl|CH=15Rc;1Bv+HW~ z-E&I+e7>Gv!!?H75EL9~AnYR6Jvs=(-pVAg!EbZ{Pw5O^tur#T3DC~BA+;z1;wa8d zvj#M$$i2lC!X{$fhdc|_lpKBU>QOS92iARCMD+Thd8`sn#i!s{U=N2pCOx%-*q}N0 z*=bIrr;>-p@lxbImm?CTA=Qa1uKIIW}3~WU9xrDp$v#eTtjG60E!0V5Z^3Dn8FJ|br;Y# z5Qk+thuzI-OtuHZH=7OH#1qDo@eJ6+TKx&o?Ez=&no5eYp%h3Sdm~WcgR1TXOtfBv zVYwTI&m~x!>4D;*5aLw(R5;6h zQ(H)rVHp0Ui*5qxLLv-xnupEQbesEkw0WW^k63DX$b|&VG{y`jq#?aGZHD@9w zJLIZE0@|lkG#m+miBT&VnyN-}6 zw9jqtv`H!ouPHE#sgjGoSHialmCz1-<6ftxOAWeTR=a>%r- zhJOO6oMg^q7Wfmyj>KC4U&w`p^-=V_wt;y!3FY&0c-}g3-kyr|?sG`9rBJs{6T4K- z(XELNgrrWlPg72rDwFuRjcIjTZ_5#!VG22{=?Dkr$lGKcwY;_GE! z5!~-tX&uSnsS~GSB5+38Z-}7`5Uvb(Kio&_YzgYU zg(w{&p&Bd1!xbBh<0?FQ)d^;63R29B{p7~PnwU2ro@5-VCzR-YS%W%{3?)zVaB*0Q z2g@C(8Bw5W@B#(sMoJR{Nyamgvvmnz+>HPIfY}4AgX_LZ*cTd5)pZHhu6DRwE;L)3 zpmE62F=;?^dvkPVv)Q)wdVND;Rf6>xz;$GHv3i)$-mXA@e?K-iH?gs?ft8gNw0E_k zx(y1E+mNTt%AnBU0KrH5*bwFs`QL1QR`L@I$+tA)eifZ1%0YKcUQqAT)s z8e%jWcVYo7R*%JM`9T9}T{@8YB$k$z5DW$p2n68s`M?+QBk@;HN4KzAt>G8|lgYfH z)9JQpfJj{s5#|XY5{aNtD56Dck|d9mO64LApuI7GWa^X2Wb1ajecR*lZ2A3uIGs)y z3 zlTAwkQ51&X8OIL@qD-Qsuyhv$p|ucNxrho9Y}2|`xDEOTEecw+?FYDO86*-E5rS>n zv=AvFN@y{a*@rsg{b=qLr6CpRz~LV5-1D6GoVgdAbM)iS(J1e%9TO7RFz?{LbOt3dBco@bbZH_0OdOMw_$XmV%A>MsEcb`Yr*BlX@2gUVQP-&VZd< za>_O2!3tls`ejI^QczVDilWFhkw~CoyyJ1aXalrwqLnnQIvvPYZe=x1(-01a5s5@( zETH9D8Lj~r){d6fZGi3U)*z^IKH~J@tdy3AMUwEAiW;e6|7sTjUjW3U2TO;s**1U@ znlwz4-{}Q>zgCgCIR$evI2?{PBz>KRR(Ij;<3(IJKP7CpJp+2|*^>{$@+v3_xR>%u u#geUGuQH0)r!pqYfZJ_);(s2~f9wYukV^15?ld0&0000dIT>^aD;pwFhvkBWZF9u_yzl#T7>be(A9#6qA9z0R_kI2#BJAblMn+_(xWgXp z)x^Y(aU~*~mrN!j#u&8LYjPjbSVV|M zqlgH}WOAE=Z2+w`0JF=DpBVvT!HUHgxOhTStyXsj)M_dX)2XUa{$1Z?%%t#v!l6!YPE`pF!!SqBZ9VIO`{fKg{!CQ%@q_)0TE&B zX#T&~KYW{G`o%n@)&kcaoG%s1Yma6gF5ce++)YpR>n%B2 zd;W56>?}t*`rfN5{Z!0D-0bQ#5jh* z?s1H&GkkIs;HCp`J9WJsquw3#9pY{FHP%`@&%^UP9LHg;oX4jQ5IcSgfIAnS5js2o z;P(KGHj_qMSt&28{k3+I*%_?Q;<_$MDGH@EmR1*7T%BiX{5jKaCh)s002L)7#N%;k zwn#tuirbrGbYP7Bu2Zc1`pCkkd9vS&kGCyTGaHTvr-2(l8?X*MO+Q(k`Ug*NS(ok0 R0GI#(002ovPDHLkV1m!b5pntG34YV2B5Ev1Xb}>9Ed&=)EnS2dx+n;W7HuN@3u@g$Y!?_6 zGeT)G;Ia>BlF~vZEk;bU(RpX?J*R~zN;-Jpa<~W1bAR`IpsH-=%(S)XX7PY++Ow{% zP2)yY*DmRFTD|u;=UDa5IkMR-sZ@&E+FDv#TIlHLFsnIsJ*`+Q(%jq(z1d-19`0r4xfP*E-)FP2uY;O9|QPSs`q zdp-ANkntyjoSgbfa`fI5@bGNX^{)YLjrBC{s4U}xUPMF~7#JW30*o;<%)aMHY=-!y zYwT<~#PWw^-KV$1_lM8Ka%+<)B27UoB)#wvRmECMJRYaDwUx?=5e}U0q-t5?5y4uEwU!_V*p-{7tfmS2hM<2A?o48Hp9#e@ zS^)2Sk9VS9{*IgSLIsJ;3nV6lVTdt?8apDY23e?ol7v{6-hdwaFi zA{|~zb1ckIUtPoo85XmSZ@(-qFLyUAQz=VbslT0@o9+(1Y4D-`P)}YIy+^tyodj^ z{+^yi^OlHIf>bIc#u&8L{PtRFve_)jWRh?=Oe_{79*?j@H`@FxC zk@=YfmOXi5QNYtLD{#d{yX6YBfo6S=ot_u8Y(GvgvXi-wn|Sl^`uV>A0PU-1s+6rl zf}nqbrS-eXeMk|o6wB*dSQc6ztO7WWgNTs$)QAy5yAaYt><_02Mh@dl-6T+FF){Ln zlC5U#g`c~s0C_Wqh_Gi}wya)wMx$?xU@VS3c@IYsWspuk z?cMOYVHgp?bzSb?IKxu?lHkTT_T&{j{t~LNfz0D)s2|1dw!XoUs$XzjH{$VoN#)0= z`}~fB?W<_ob`-%9CD35Yq@>D&>dKB`nWGHc&fSty$ zj;XOrxY*3+)-XNviVJ=(4b3sMG8YbA?Al%d7;SnTrQ}_9oYv_aTlbu#Ci8^1x08$v z_H^<5%6_L9%ek{(VmT6ciL*CLHp z6SJA`tW~WwHL5oL*D?Vd+t;|z7H#%*Y>6O#XK3MDwx|2tX!>7U`U|}yf1r0tD6{|o N002ovPDHLkV1oK8Ta5q! literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/building_error.png b/base/resources.pk3dir/gfx/icon16/building_error.png new file mode 100644 index 0000000000000000000000000000000000000000..a342eefc68fc3afc61b30ceaec06c47d306904f0 GIT binary patch literal 653 zcmV;80&@L{P)@1)Y*u3o>2#VzB0*hU9nol%SS;q-oY_-I%jI%JA`t)z!KzAc zZ!fA!JRUDnPy{f>05Cqk@iMDm1w;jFp|9QGy6*o0p68*e96h+Qt&tGg9bjUq5>dg( zhJs2vO}!l>*l`8Nadrj(9IMUzyV*ME(qls59 z5P`}p;(i7d?4NfupT5qT>)n~W+a1UQt|hJpvA!4kORE@LdXCr}EfpULg^wWF8C2Hk zI@gMLU)j4iMY!Wa{ddpY$^)#i1Fq-kLVBLHtTNyvw+H}2qkS)f` z?(TK-0aaaIq*5uh)?$odX*R}?$z(_*5=0^qVzC&Vot=TDJ*6u(-}i||qX4XgRh9Pk zc2t#kJie-eRe&)DfOq4?n^^@bASzf3mkt?R*WDQKJP%dnXx;p}jfCp00m<}ELU zPO|5~w(4>&YX>5N5swQkU04;YSOn!qc9z2pr^$JR;K=uZ?2-Gy@G>AG2ZLoLq_SVw zqY)hAVO5y%Dy!j5`ZXegV;qb% z)Q0v^7urvKRg|)l3U=?<%jj%^p>K)#yvOlU0BdZIHKG%_@xXR3L_Gb9ym5Fo+>0k3 zj&X_Av~VhVkxw&&^iTF{ZDs4&(B09oBJjNYAwU4gV;N_X2py}Q>qFrQfnWtgUxzs6 zb_Bw6wddD-rp+RHFR*B(q_QA3`s;yCE#?0MOlp8%R|7kz00000NkvXXu0mjfed04y literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/building_key.png b/base/resources.pk3dir/gfx/icon16/building_key.png new file mode 100644 index 0000000000000000000000000000000000000000..8b79e30ed9ecc6b675b5a097e75c2bdbfa6d1e56 GIT binary patch literal 705 zcmV;y0zUnTP)Hq$Cs}SPFq*^i6iInN3M=Jz}^!yqE;r7tu#N~*Zc9^0GN z)|7EeL=ux=FeqAUlu~SuN-4tOFe4))`2BvWs;X#dX|cBVcz0^?c$`2W0KiUIL}+eq zMno7I8cM1l2~bJ_@G-P?GA*DD7%^xK=W7*?Y!022)Mhwbq zRiHE&qd9B$a6D^_neNBe54BG`NeKYdmoDzgu7AHGGi!m`%ePtl+VyDcLG^rH=k&WI zz;PTzgio^tXc3eFqoHK=H4R1M?5{aP^zR^PIW+}&<<85&TYX5HA!YIzD@|k6B(_-rI|qroOg#&2 zPKMTQcmX;_ZsuCX`fwn#km0#Ot`@ganK_3)`h)VObBOyMOD{7%u!gmoe_a-@EGXXBXtR n#g?NR)6?O**LtS=Q?2_41-p0PftuMh00000NkvXXu0mjfc@aOR literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/building_link.png b/base/resources.pk3dir/gfx/icon16/building_link.png new file mode 100644 index 0000000000000000000000000000000000000000..a340629ac968cd8dbcfd651458fe48339c2d199b GIT binary patch literal 668 zcmV;N0%QG&P)6&op&*3N9K@Tao`hUlY4MOlS^~C*LXTc87OyG2#h-Pn~377JF}e`F+?!If#D5r-~8V9-rIp;7+7Yv!eL{Pe+5gf zkNf)z{U%PCt!lMu5JI5qI%bydPN#!XsRWP5gFqmFSS)6m-7#OLO(qlg{eE%24Cd!( zG%9R9pPy4O2jJQG`toyH8DR`U0cudD2zc~B$7nRV8ZaJ@MV6gA{}wh9xV;?Uq$!K6 zI-M%eS$0Yd>}~7NH0^o-U%T$^72}kzSHM5=z_0a9R=*(>P%`a>!4y1sIJsWIIXS~{ zID~XsM5EDw!{I=;-9{u5fz4*a@$n}y%5*yYS5cI=l}hFP1>nue;XSiW!g;PI#+gVY zFc=KbY&KCS6kxa8`TSuvo6%~uk?M5gR z66b6-3$>+U!(sjQ^5E4D13VXi*QFP?Ow{yQtBh{xlQWf}c`U;L3r zAC5q_N1Hr`sgeYM=;V;-)abAEOzNp30JUE=t_qn<23D(8_;^WRja~bG^DcG))(1_z zg=8{m%mRA79>U=;yk0LX77N;}iM3h{k|e?B^TFkEVWS#V)Nf_e!_hJz!RGI-NOYZ?JI_RaHAI;og7fL3{3ZGN}as0000C#5QQ<|d}62BjvZR2H60wE-$B_jGX#(Kw&{<9vg>5sw;c`@i>p z_kaC=>wowE^MCGt=k0FV8~^>E{g3+d|7HJ+|I4@QcRd)^xi$V8^Vx_G`+r6+RSGlL znKt8REw4uuU$^wNG<`ek&pG#xJ(Hh0`*ZlR^+%Epor$llpY=cF-^u@z|Ed2wufXdW aBfwxkOHd_T*GCNK1O`u6KbLh*2~7Ys?Or1Q literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/bullet_arrow_down.png b/base/resources.pk3dir/gfx/icon16/bullet_arrow_down.png new file mode 100644 index 0000000000000000000000000000000000000000..9b23c06d7b4f4689dc8c9fd4e9d4d1f199fe376f GIT binary patch literal 201 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-%M_H=O!(Kw&{<9vg>5sxM-`@i?U z_W%6<>VNmY^FQu?=k0EK8(;qS{{MRQfQxhfe|^4DBSLrMi_=~IrT?G*6aRH>fZ%Fr xHSdzT`JeW`iC!n;=N{%MvhUm!=_W-^hCUIl<$=usRzPbQJYD@<);T3K0RSKzPZ9tC literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/bullet_arrow_top.png b/base/resources.pk3dir/gfx/icon16/bullet_arrow_top.png new file mode 100644 index 0000000000000000000000000000000000000000..0ce86d2b2bc8eb047ca749fff00716b15c5bd9a8 GIT binary patch literal 230 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-%s@N{tu(Kvs0!a}YF0}=J!QSUY7M7z;-RJ$7n8*6-IkwdUVS%nn(+HZ=IM>KhySVgJojLZytKsQlJks9 zg>q@PUpbdv;&|+P!{NQ{65)mBh3B(*yP58!PISKz-O48F^~6K0e}RJHfr*NaZ|Z(M akrr=d7xdAvd!`9=1B0ilpUXO@geCyB6I2-h literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/bullet_arrow_up.png b/base/resources.pk3dir/gfx/icon16/bullet_arrow_up.png new file mode 100644 index 0000000000000000000000000000000000000000..24df0f42129c291ddb3dd50c8ba2884dc23a2c43 GIT binary patch literal 201 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-%M_H=O!(Kw&{<9vg>5sxM7Y}K&+ zaVqV>2dg?$?}z`N|7UG5-|D8TLf!k;{Mi5T|C#@x_qjwjYRvdu`ttwR|Kb1QzwCco x|Ef}l>({^Sf7bts|6%{R{?h*$`OZ2jjF;IsFRaMi76-J3!PC{xWt~$(698OLQAz*+ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/bullet_black.png b/base/resources.pk3dir/gfx/icon16/bullet_black.png new file mode 100644 index 0000000000000000000000000000000000000000..57619706d10d9736b1849a83f2c5694fbe09c53b GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-$h^>lFz(Kw&{<9vg>5sw~gS5O!4 zr|{HuUFIBKiQyL}eBJ-L{`UVT|6_O~L{G%N{Wbre{kQtZ_0LvEhDX@>Vt8IAj)#jg!+?Z23wnf7d! zNAH#A4i6V)y_WtvZQ1hT)TAWgjoY{t%BOsI;8VOzQvNniDZk5xCy$)UQWb1PRjRoz l1#moJy|?3|{zvx%+XakOf%ava&w)pvdYw!Pm*LM8> zx}xa+>1^FUyPR2ai85fP3-jG?K+XRr`TqZ3F8Kd{o8tf1T@L?&;`fL$0Oag{XV?8l z2Jh=7{)5DcbAc=K<1cfQ|NjSS`ccO4{~ZuN%wYZx6n{dL0f)n-8cwFD{(e@j`2STU z>;JncjQ{ugvi#ZM%3MW!EQHHe0ByVvjfKa!G>;}_2nGNF&fymKM6jp;0000iurf=~3UFXxqI7+S%~yN; z&QFMWB8?geDax2;<5v0zO%9O+HCOhCe@lCtqI|U`n(Bw>E`n0X60GiU=_L{j`ZeTrWl7@6TVgmzQ|3 z5;Op46VsoczbZwwqJ7S==^_3_&=Ox0MY;dOCY;|ap-3z08F!}8RFQf3;+NC07*qoM6N<$g0j}hYXATM literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/bullet_feed.png b/base/resources.pk3dir/gfx/icon16/bullet_feed.png new file mode 100644 index 0000000000000000000000000000000000000000..1a0e0f18f8bf7b2c5bcac354aa09be0ebab3f284 GIT binary patch literal 262 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmUzPnffIy#(?lOI#yL zg7ec#$`gxH85~pclTsBta}(23gHjVyDhp4h+5i>J@N{tuu{fRlV-?hn1vRw7=~`H|6d*}wJTwx9NUJ^A-PC{g+mZ-(ezrYk@A zSA66PNIvzSX`%9eCjvLPn~<&zkcB#E_)bRoqqqjuJxZi%ZEMd z&v*NvhWGUx|LY&|dWg;8xl+M&hVS8ire(E1*YzxOk&ZD2*!*kie8d0ob9Fh%G9Y=r;n&8^QUAkdX#Dq|D$hyKfc&Ml|8p0c z|4m?!%b@Oan%jHPb>P21W3>NYd-<1_&1WU%JGUHShzcVz!>-In&hVRPdDrmgA!XB=w& zAG5&bziK_hADjk6&({3E^3;U?OHcIvUwEwR|Gc9eKtr;M1&07*qoM6N<$ Ef*qF6bpQYW literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/bullet_green.png b/base/resources.pk3dir/gfx/icon16/bullet_green.png new file mode 100644 index 0000000000000000000000000000000000000000..058ad261f520490be9d3fc2e322392fdedfd1cbd GIT binary patch literal 295 zcmV+?0oeYDP)ef43{&%10 z`rmr0`TyJtv;LcOX%laN^>UMjsi!CYUwmcZ|JfI2{-1ED=f8fLD)C;hoM$LyF)D9~S@raHZk@o8xu=?=BAbx-CyJk|+c2F0@|%^WDn-Kc3b7|M6nh z{|^`I{(pPa@c-rv`wv7JaBHSX+n2kY|Gz!R`v3h=@&9l4pV{WeA)K@>rLPPXC_&Fo|~u=OHx8Q*=y2zb-wG%)4f&?mZqzQ e4THQu3lFzu{izqk|8%^q0F(5@h6w@ zuSbE=i9QOwKvPc#-iPCap~BwXFHIr_gU^WCH%x0(Cm8h3e{9o}5`YUO%{ zPiLR-*D%CfK42<(c~V-?1q(}8{p2N#A`c~!wa4X-$LfsZ0%WH-1^Zy?%r3<3e~Rbycg=S_Egdz d?>~Yc*m~Z+JF!m3&mHJ+22WQ%mvv4FO#s^$Z2kZM literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/bullet_picture.png b/base/resources.pk3dir/gfx/icon16/bullet_picture.png new file mode 100644 index 0000000000000000000000000000000000000000..386cb302f16b36e4ae67dc9f0aea1b4a051c22c6 GIT binary patch literal 470 zcmV;{0V)28P)``2`~zsHhc-<7$F60BN8G$;h9Qc)$m zPjaF(rLGTDO~!4K5|M!ls#FRA{~+9_mh$B%Z0UrmNw|v!8R{*)VvIsyE!@@WjQ0Lu zG45gF&|%`^8m{Z2fQS@JKovnbzF5W>!$F>t_qCIs%wUXRcKm?<7uRk6jy>0U{$XW$ zkEc3qYB0utYFr3Nl5}@-_vnko8F3szAXJEHK*aJ;t?e|ae*4Gt7rT9)_)n@C%m4rY M07*qoM6N<$f~O_aVE_OC literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/bullet_pink.png b/base/resources.pk3dir/gfx/icon16/bullet_pink.png new file mode 100644 index 0000000000000000000000000000000000000000..0c9f73e3f58fec93410ca240016ef0522241aebe GIT binary patch literal 286 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmUzPnffIy#(?lOI#yL zg7ec#$`gxH85~pclTsBta}(23gHjVyDhp4h+5i=8@N{tuu{izqk~P;M2a(o?Ym~XI z^0KETC^sqCab0$O!=k-0z-7w?M;1Xr?oLLkMCemR4UW__o=Snfs{&byph%e z=77^@l_n}qHB|c9pq{s5_I-v&H_y*pYjU~LY5(eqL#|WUf--*EUEAAGxHvbtb|TLazB;OXk;vd$@?2>?vIZ1eyC literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/bullet_purple.png b/base/resources.pk3dir/gfx/icon16/bullet_purple.png new file mode 100644 index 0000000000000000000000000000000000000000..52ba5036b95383f6c14176ae33300b859e4d27d8 GIT binary patch literal 294 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmUzPnffIy#(?lOI#yL zg7ec#$`gxH85~pclTsBta}(23gHjVyDhp4h+5i>p@N{tuu{izq(ta+-M44kBpIe=q zx`X8@9}gS%(w5FYFVig+ojZ_cD5YzW==f41NB?BP0gvSsuL~|cX5(?+BsuSEuz#(i z(0!iz2et`~ZLD6*`-~P&eW1fC)8o%D^YrBE+t1g1f3V_>QFkv3+p8U`|6X{$=uzRE zYb8;$Jas}77I1~H-7TjsdDijKvCOxpB#s?yRPsxju2(W^mhtCPasN(mSRK@VvcWVc q!c)dr)HS~K;xqxD$MKK)8^oXLysE8u-|YeP1B0ilpUXO@geCyg%6BgS literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/bullet_red.png b/base/resources.pk3dir/gfx/icon16/bullet_red.png new file mode 100644 index 0000000000000000000000000000000000000000..0cd803115831933aa171497cfe9c1af983035f86 GIT binary patch literal 287 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmUzPnffIy#(?lOI#yL zg7ec#$`gxH85~pclTsBta}(23gHjVyDhp4h+5i=8^mK6yu{izqk}mh50EX6wkMFui zZg|fh<-*g%H9O|;u|DY#DW^u;K&o-|vHe`x?xbw1zYx$2><(A#;6QU!sSfhO( ioL~suuJh6Vfb_?jd)=>7iZy|bXYh3Ob6Mw<&;$Tq>~Ep~ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/bullet_star.png b/base/resources.pk3dir/gfx/icon16/bullet_star.png new file mode 100644 index 0000000000000000000000000000000000000000..fab774a3288143c3ca5ef4a6354476a816d20b29 GIT binary patch literal 331 zcmV-R0kr;!P)clpQjpWPb8b##8}RLd@5ygx>`#(pz>k}$oIkF|*aK~E`Efn%|Bp+N z|GyqlYyW&e-v0A$8BQV$NSgWcM%Moyw~GJ&deHs<=iR3N-_Hg9|8m&q|L5&8GYK1T zJ%$-*`^F!)N`MCR01asV|LsD^f1vFfKW>v|CMpboe%Jke!RPC#5QQ<|d}62BjvZR2H60wE-$h^mK6y(Kw&{<9vg>(S^W+6Zii9 z|Nhthr~iNb*Z!}6uiN$Dz5neG3a-`baBX8yz1H+_;eX)`ni0%X8XBDc-`=Ph(Uan2 zYsR{H!kvIN--9isvHznRsC#5QQ<|d}62BjvZR2H60wE-$h_H=O!(Kw&{<9vg>(S^W+6Zii9 z|Nhthr~iNb*Z!}6uiN$Dz5neG3a-`baBX8yz4q@v|B?28{s)#N@CGn3@%_y|zAV9T z66e<&B4?b6oF&azg|C(V&1ZbI_D}pL`}(^FT2yXwG1Ph~$Q@h8mJYOz!PC{xWt~$( F699+YQR)By literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/bullet_white.png b/base/resources.pk3dir/gfx/icon16/bullet_white.png new file mode 100644 index 0000000000000000000000000000000000000000..a9af8d44bf3c001adc41e3774f526bd1d1448b1f GIT binary patch literal 201 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-%M_H=O!(Kvthf+1gnf`Cilxr3SC zCq+y2HhAz(;&}R`x^q^&(wiOs&2u-u^*?dO$=Q}CfYva0y85}Sb4q9e0M-pfO8@`> literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/bullet_wrench.png b/base/resources.pk3dir/gfx/icon16/bullet_wrench.png new file mode 100644 index 0000000000000000000000000000000000000000..67817e6e5a785b0a1f35598671f5d96f433298f1 GIT binary patch literal 448 zcmV;x0YCnUP)7VG(pVO&BhbRxxA@I^akcY^KxeXPXwzY<`A1LBLBqoDFV3>hv=E-l& zLuDq)&@>DpLa1JUfu)4d;axw6$9paSuD`@Jb3oHHkE*I&S(Zn!SWK7-&@^p9QIt-r z)dC>|k|brO0%TcUvn&ga<3JR}p&$rGBofg%jys$Ph(@Ds(=<`9*TM7rZ8#i$D-;R{ zg+iad0+J-niK2K}tyVz@L8VdwAq1sT2`tNYe+2k!o8mH!QPL>Fwr%8cIq15Mcsve< zVLE=l-!m5AjJ7wBe*DUo`|u?iI8L1*7z`RL%Wl#%?WQPder$c_6~(fb3t z9fO=s)r1xNys<0toy$Ta)Ef4L9Xj#;LuHACPs?SaC)p1!HoK`$|DN0S(B^2t{U;k3 z{z`Gkym)-$S?qyE;12cK15evqWFMuk`FjMfG>*N*A!+l(#* jF-_{7+4G}*QQ$ohjSunXc9>@Z9nawD>gTe~DWM4f1nGD{ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/cake.png b/base/resources.pk3dir/gfx/icon16/cake.png new file mode 100644 index 0000000000000000000000000000000000000000..4ef151aeef90cba37e483fff6db393e3f3c215a0 GIT binary patch literal 676 zcmV;V0$crwP)zhG}s4?zzVdkG3gj2<%zA*q!$2x>uX%NDCytJWaYrPXj4 zU1!!qgC^xq+`MO3-MxA@QLjVPPv?85H*G=(KHPIYzrN>QxF!Im4#IxZ@krPd?&kid z_ZSiplU6Pr0XN$E74*}446)Vy(5l0Tt?p~}o7mB#KX>@D#~Be*<>IiI~I2tp#x z12i!dI9uRn_jAuUmOh`s_#3O#Q@}+t$Jn&L2-mkQOn%5i(=-?p`Lj?c!2VW(AbHes1cgEB@zPzW^m!s{<8 zH^}g>l=Q%z`79itWZZZq>1T&4kE_!Ru7HeXVR6SO2noJcy-wyON8U|XUoeAf zHk*)T8OiUqhEc#)EX_nb3VMysq8mBfIar@DEC@xNQ&ko5*l*<1J}BWse+#xk2O71^ zZKRS>{bS{FIWTbz8yidq6)TE@^|cgAnWrExWsHLC$l+FDW*C*!T_{XINt{JZ95tYc z_p#09P!;b%OW8qQ$`}Pj@4<%r;2b2&DJYXe*!EsR<%dl-6KGEyY2+ae zQs4@dsSC*31|bfe!20Q-oXHShTsI61&!<8X5%II3+V+8k*E-I+hzUk`L)aOtuD0000< KMNUMnLSTY|9xOrt literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/calculator.png b/base/resources.pk3dir/gfx/icon16/calculator.png new file mode 100644 index 0000000000000000000000000000000000000000..701a60a5a4d5673d0e3dd3fc8f316a2ebdd7fad9 GIT binary patch literal 543 zcmV+)0^t3LP)@VozFAzEvI&~0#LAwY>5FK39Rg@@bp>BeO zw$McyP2NlT?u|(Uk#_LH<=ljK?mhP;k2#J5heX6H%H{HXCX=~NBoZlARe>=^i32c& z5WqPH!!SOV%jHw0Qn@9fcc5CW>Jq=4|6^OL)m9$QSCC95(-PFn^7EgPn-5p9Xf%2j zT0v11s^jrE9G#rvGccKoT*Is1-&Wq)um?di)g6Ha$O`*a;Q$Laz(Aw!N@+sNvdAvNPK8Qq^wr_gSuSaWLG&M-o9;vBq+hGMlxGxKZ0_1Wz znv69PFh5E+M2titU>*W4;JO)kE$QxbPq19@+D+v)+U|OcH05hn- z^9BftDEsz1&z7-itp~p6;XLO&pY!G6%mJ8_$z&S0+uaEUg9wMi zh(scYMx&J3p4I(+KO7FnP@zzmSkG_KVzb!_V*ZBHGE)W)qD@1Djh;ybvT`|Cqe%}M^Wu8PdaGPVM$wTbzq|{0}G7TcW!EaA!?fWL5dnF z2D1#A%gQ1{g%n-+HK!)Dlhy}{SMT#sR?}5CT<^_$KhO1hFK%8Q0G>o5QQGbHy4UN4 z-|t5t5I`^(q@BEzx!diA)oSg?WHKG`{1kndOr{LiH}UWKW;UBQh5$~dv&;3qNOBK< z6Dck!h5#fUsZ-Y;K)kqu^Qu)$YLd8c>lvnXFEC?xNzX_*9FAdt%jFsXCOPxeHuELp zFTfqg-O+$vuZLo>h+A49r%wOWlrp#YD^1Eo?) zL9N-#D4jluZnryn2R0iWqF%3~TCHMjZ4ISTiKfZra#Wd2hTget8v!s|Ec7rG3PG#Y zqE@TXG#ZVD!hAj-R4NrsU^ZKZ0Y;;d0$QyWn$0E}jRs9aK$S`b<#HJryByEY9z^Wu z7^36+8mIXIK&#bJKqL}@!C;_}a5xOTUQa<$W(IF&597;275Zqho@L z6tK9oL;;;nhpOFf57H3D&j|6EGeai==5_;&5FOuzq!RQ3MdquSQhNU0$7%aMdZXDe6pPbIMdfFJbdI- zo#K;Stn+@~=uTRl*mol(KG5Bm6XL_wF}xG+!V{68w>-|5{uhAg>BRnd?u%s-o9lIA aCiCwjy#9~3ed^Z$00005{JVI0Q&7rJd-bKnj|5%n4Y6@5>kN(HX=3gQZxSrZA^D5`8Z{esFV$a=C&4Y&IK|N+p5V^n66#)oqx|kqlhGx5);u zsv>-l96t2NFEmRe1Q3hGh}cmhru%PZV>^(XtHf%s42#($e$7cdlnQdcQ79CqhaHY} zyWNhyM|@1ZpfK^W6`$NCSeYwDeEb%?>QfjQ=vx#MNy1E(6}NLiqLca7_c-C zw*4#yshx1P6=Oh9fCs{Q+!ZvgX5YGU0KZFcF+ZJhDUou^;chBKPt~sF{`&m~w!YgI xP*SiXDXQ3;es!-nZI>P$eqOh4_jYDZKLCCG2jOQ#mq`Es002ovPDHLkV1gc3OCJCL literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/calculator_error.png b/base/resources.pk3dir/gfx/icon16/calculator_error.png new file mode 100644 index 0000000000000000000000000000000000000000..0bc4288a47268f2dc44b7ece051373f6be4d8e02 GIT binary patch literal 731 zcmV<10wn#3P)Mg|`>;I-sPfu@FiJ7-B z5|_*6qaY1OALCy(e|OAov)Q`p_c(zliX0sd2iiOxEQUZ`q}Qmfe}3P@ZZ4V#n3SqX zy9GjBu_){nSP+^Cn6XCPzUJeo>pE{*1$DkheC<4swzh#ltQNEGXEGTqEG)oow_|;M z9f?GOU#mC$1U)}ypq92_nr5>CLMofVU=V>ofS=6POa;;Zpfo7p;PDas{`LZ9qkxJ6 zgBU!JWf}2!oGVycTf^ewB3cz0o~{tux(2cR`6Zkv>_b3LWEKjA5Dtg=b(n%Hm(Ih; zC*bb%fc%<=w|^W*TRtH3@S?4ez#u$WSy@3W7USJtU6t|a)qQmKjR0jCso6Ok@F-{} zIT&SaxPd^^wVHxRB*F>K_BwH@+Y5I`38wmmzMlzFOylH*C=6A-mAZG%U2CGQX-0Bs zNunrJ=7PYJpT+6WWtgR9TB~4av=64XiB?w@hX=;`Hh zI*t6hI1cp;!Rao*GPdaBOL+Y(OEXQFtyZQ1XqF;uNpo*7jv`sfxNoIST{2!@t*;BJ-ko6&RX1Gnf{r!El>X(K%C+p|)lFLAvS4UDUb| z(NtO&f_mYYleP&VL@lBi!?ADAIn?^$ssrbJ&U>D7KJWKA4{slUKC{{EU07IXClU#) zt*s%IN+F$2^GffOUtV5DEEan|K0Y3zo*&MSxw*NjSP$`kJB~ym?|J}>i;G>co+`{w z@h>M6O3?!#d1Tk_KZDkn$4&n$=mRAf9+Y7Wy~gc_Z+MR^9*_3|mX?;z0D94U>yPF; z;h%uV@h9g4PEJm+v$KOnqk&qjhDxP^t*tGTN+lEu1>|zMzbp8jfE)UsaB!e?Vdk_`FT#F-EL!le;>QMyJ$9>tfpSCvsbHCu6ZYZ@@6KJ zK``~9pS5{dQ#!r?FjI-L&o_V&2h=ku{#kH>>@xy%X(Lb>Vb z>5rqMqxU2d$t4B^gP}78CX0%K+cZ3cd$aUdYMf{m^v_~~m`weDl+&_@K%&-6e002ovPDHLk FV1i#7Nd^D_ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/calendar.png b/base/resources.pk3dir/gfx/icon16/calendar.png new file mode 100644 index 0000000000000000000000000000000000000000..658913852d60fc6ca8557568d26b8e93e7d56525 GIT binary patch literal 675 zcmV;U0$lxxP)w!? zFisFv!T|cmRtW;1f$>$s0G>^*GP-h`H-mzTP&3`b(d;hDCL-{+T2LSiJi1S%34OTG znWn~v^Brk?FQB#MFuosf?qnt!t(A%g#tAAA`tV{p&t%~)6GMus628BV?|aP6=Lr0O zrxPn=6Fy3{fE84gngF`mQ;ZG4p#ul`mYb)mJw@Q%q_eddamvg>kv)yI#B0M!3sxev z!1s9dp#Z>KE{BK5@W%p1Kt!2cEYj2vBiUHDJ-HCTS{r%b!`Wj=!r&Tb+LFBfRN!=5 zl7aC&Ul)Foh{s4J>JU)^p9+C-Q44MR8(8|WK})8dx#e}T%`v`wFOp3_q9I1QsXihN zJVaEgK9Y|1KAJgEb`m$%VXVVh!8pM>`_Eli`}OBJfVb0i{tF{QT8%v&>u>-7002ov JPDHLkV1feuD8K*! literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/calendar_add.png b/base/resources.pk3dir/gfx/icon16/calendar_add.png new file mode 100644 index 0000000000000000000000000000000000000000..17679db6bdaa6771296fb016d21b0fdfc79e48b2 GIT binary patch literal 723 zcmV;^0xbQBP)5ETnpqPAn6zU<&FIp9Il1xF$N9eryjdy0$g_1Iflt9aIG62{ zJh%k%4xHmhLo?3#;voiuIS4Atz|yRg7EJQs@{lI*wgUi{`ac_PABetl_Z_I|3#8?`eD|ed6f0%TQcqH8_?!MPbDcMaNaP9 zID)f}I*Fo?b1j|35nOoE$%C)^xO?7^8AZ<;nKNMoiOUGW!7B)eqks)d%85f*Ut3O5 z2y1J~34@4P(`OKd5v!{!vZqb$PX^8#GKfRC{H%*7-3NGlMMxrkzLPKvXnpw>efz<- zL+i*V2}yntup}dJsUeA?2-Z}W0WfXy6oMdN)xt6+rt=t6;#s+T8Fd@$sj8kz$=Hk3 zZm&ETLN;{(Q5bOJWj6qApFR-~(46b$`TH|e&0c^HJqyOKzz2@nc}oH6k;Ja!@6_`> zujX8rB$7<5R4{TFutjs$=EoolyOHUV|OXy7|=wB>Mn!!NA5kcv+BTC4y7002ovPDHLk FV1h%aQKkR@ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/calendar_delete.png b/base/resources.pk3dir/gfx/icon16/calendar_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..69a3b10ad106f0c1603e5016097973b248988c05 GIT binary patch literal 742 zcmVObCawiW7N$cdk%fiWKxW)*|jDAeXeGGH=bv+%Yb0At;_2hK@Oz=OUd zs6-?p5s4eiKq3J^HYb3p(tNXDf2NI|X&Y2k)pL&rR8{r-lc>JX5!F{Zqn!Mn)@{e0 ztExr>#tEWI7{JAjA%ei?Qs)q109T(4(LQ*HM^^+DA=cHzg0d-OO+?_2wV*&4cx9KC{J4yRV93}AK&+g zwcMfM)k|8NPohPoEGb+E)aL}OpsK_IXs9iwqXp(vRMOr1iH6!@@}8DaG~C6!t$UeV zwUG4d+e~k3<<9EZE+3+)0|2J%w4g8ypIp?PHkaI_hqUo z3Q-OHH!`*J78Nt{34<6TNlVY5uZkS^{&t<)HSgBt&-pBVMkBEhC;4*D*}UiZ-t)bNi10tl2Ds4Bw_k+q zN_0qTjnd$0jZzw=1yAWwrBI%rw0?AC^W3lvphb3dpFZx^Nsl-4-_nbkW% z1e6C_f$RF`R1(}2BwcV_2KUzEx@ycQfnPodp@_pEqiw)f(B2w8H6A_Us z&HlZrB_@NPYb08~NBTNzMFt}BwX;fEPOOdD0It$#5o`;pTjE%j$<+sOYzt~y<0KNh z7|JeY%G?rqyI$fLDY7R_Cu{1=iRl&uuq}fP;Q%$Q3D$>$)IN^0y5JQQfsh6SZd0{|4;Lu{NrgNbv>7>S(4%y3Ed7tnpb16j6@?@kB+6a1+I zuuOxxjvjLQKCoEE5iDLuDprBz2+96@x*OVH)ky*c3)4Sm19+b2dtkzhfjV+0&&HD= z(PyWa9CR4z&7-IFCFZJ=1akAyTChxh6S&H6VZqESIvOjOzkCN{J~r~Yriu1jy*$73 z6r;U$IB>~PU6BqP~898YX3J=*#1Z=w1DX^nQc3%5aJ00000NkvXX Hu0mjfn=oBS literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/calendar_link.png b/base/resources.pk3dir/gfx/icon16/calendar_link.png new file mode 100644 index 0000000000000000000000000000000000000000..6b106b9429aaf978ef93ef331a3a58ede07d677c GIT binary patch literal 795 zcmV+$1LXXPP))y9?D}-jUWvgMWybY$46!FOgIME@ZA%%FuOX7|428g%rR1ovp z*vgiRA}dotRFqhtz4&&XgOmBP_2T=S-|zc;f1h*Cvpq=wlKw~ZG2jX*`<1C7(`&`tbA{n!tvE#FW*>_g>)FHj747mfgZ&YfT+`Un4_TfNJ% zBY^4E7ByiO0RuvyHy1G706MaOw#z^xA86nK>a#%A8Jd-JeZUc*%Mm;TkYR@$cwP=X zl>$$SfyqL^o(GIx0|p7K@-)pB8Q&!U?c~14PSBqZ^pT;S9H9F;&`E~d1wbnSv|OTD zVY4RzXdxeqH6OkSuqKAxe!7m##CywZytmKA*Wg|hIr_x}KtHvH@b3dUU|}`83F~YC zw)p_;L{j@rl#CUj*jk9`w|;!x2;-`DE&-?1Axz{KJvY%{B1noFUsSHom7p+<8Dj9CI^RDy~c1@*LA9kS(J zNJ&XKNdc;n6@-56V`^cY1`GxR{C+=tJ|CP;C+ZvYFt&HX>-AF4?RL{lMn;B~0+d5O z3TW(^z-^fVo~0$^Gr1&i0V0tIO-)UZ%jLA@^Z8KMYAA$Zm|Y4`m_K2M0Lm)rpwVb3 zAQp=ujmv|>;ef~Efy?EB)oKNgcOHSQFa@Yoswf4N_bp>P9K-!yGbEBy3XoMO!QpVg z<#LgknMuXg98MaPRn-(wP*4z}fHKoZcS*-mBwPIm7qjx9y=#DZ$O4WPo<})uLy<0h*&I+6735Ff^4F5qzk}@P)Ff}Nlc zJ+V-1gdjvrBToYb_&=5JJoz%#Q=n#p0PUsg;0_wW6hzWF z6d(Z#0TH%uy+T9>YJjQ_4o41w#S|V(NC8qn46yPY0ExQO163;l8LV%BTT)_{lxVdB zLqhH!O}vfXt+G~AtirG?JdRPE!p4;(u<%+06sOr5$!l?%`w$ZJisblGeq3lk?M znK(IF&Lv~|%q&@!^#Q8MB|waLDd+L)A8Bgth=QmR)CiKix0+Qk`lsOTj2++4X|3MA z_x{3e%gn9zko@i4h1Ih`tu0ZJsAx1qji_-~z~gH-D8wdL6`?9WFzi$qo8J^aVr5)w?g*$f-IAT>umA~g7`KN%tnR;#U}<7 z5hMW@Lgq>E$!K>yytk^`8I7CZh3ZpP+&cH%(^WC8HJ%e5f2P*XvcxkWwQ`kGkO~lt zlII$NusS59(6q0vCnq`@4S~{naJ;w4`Jc)kW_~B`6%d;_oLG1Va7$7Us|13;&iz}O z`@n5r_O9P&2_$L=A|D7_Q*>C^p+!i-1T+MZ9OX=AAZiJ?X%jKvPl*mHtAuC}!6424^=42In{JdU?xY>Aa%fe%j@!RS-}GG7@u}MX(vJ z>tJ!K2+sw+>=e;Z=V0Y$3Gq1LUIFdtdibFSPSgUs;JGo3ze>ZS-Ld{OC?6xeX_GkI zowC?tTM$B330MKQ%?H2kQ68M0%NJfGeerSnSF=wtJ002ovPDHLkV1gqb2Y3Jg literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/calendar_view_week.png b/base/resources.pk3dir/gfx/icon16/calendar_view_week.png new file mode 100644 index 0000000000000000000000000000000000000000..8fe695f51fce503e1a4838ac4a93f5b9ab95553c GIT binary patch literal 480 zcmV<60U!Q}P)@KEQ1dB*OY;8rG{0D1W!OBLkw-N=dwXm~N1QE3ov=J3VoAfqnBj^Uw zM54xfXXYG>dvA7&AS)Rd=55|*zRs-J<}fw^c=>n$4xMPD-K#DN!X#CQA!mRGN}D zZ(TUGF#(W$<^0Ccwg1U{{qg71`xTV51~7eg8EmKo6-0FJwt;A&35ej=)z?JS>H=Vx zgW<$+P+1ltJpkL>eL3^by|8WH ze>3}MeDdL&w}0&U;_Xe_W&{u=wB$OQFuT8lHo6K%Lkr8Qp~<2Rk*PT#N?1z*LjAZG z0V$SMWb~P*tCKk(rKJTl0EW#?05TH;58iGu9(7SR_g>A2D(<}aN*l$^r(ZZS?mmu3 z3%3x}wQ%n2F|r2jd;b;=GO3$dFC@Re@#xc;wls|_B8y59C9?8Bz|QWU=Kw2*J?FpO W9yz<&(0nxj0000gJ-O!jxnD7oNLq;%;3B=$mW~C-A78b#}Ym zUa~ApY&IL$YPE8+w{2VKx^DRW{x^j};R(m*^Z8S9-^=ClFHtNO4^>s2WHK4B90Evd zRNvv@{p&Eky~2wRC-6pYqSb0Y8jr^>3G5|f?PqEtk*KFqDSspqL8sF}uh+wHIK<_n z6MX#q6V3T;+&aAjAq2YJ?gK?pbdSdaP1D3|HoL3QsY$Qbi+a6|a5#)~It`Knl7dhu zghr!*N~MB8Ab@N(i+;b4$z&p9n$6}7jROaR0fNCGwg*Re{(gmpDPU86x^Us%)obw2 z=aha6oFxO>?KYy(sFbSkv{)<Xg3cSx! zV*;wSwBMGSfGRX({TECm3Yn@1ESF0eb3TJT z!7c-;DBO+#(G_BEZ~a#M_t*Fbci5Cwkwgrt00000NkvXXu0mjf2e~nc literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/camera_add.png b/base/resources.pk3dir/gfx/icon16/camera_add.png new file mode 100644 index 0000000000000000000000000000000000000000..08b5da9891cffe3ee397f528734dc5de406c1c53 GIT binary patch literal 800 zcmV+*1K<3KP)ZO`s5Iy)3 z^blxIm6b3;gecZ(Yy%rC)TwiGbGzG}ySMLLQF<%r!0&t)?)Uq?-}!y#FkRR2KTG1< z)YR0ya=9F+R;zWjT8&jI6_cVUW*#+7V-|}=wcG8l$HvA+dH%@ANFRlt)6>(NEEo(P z5=AlB+uIASh6o0tU*6*C#bZ#Hp5f8^4%l3sh{qGxvf1ooBHIXD`he*5dLvz3U3Qnt zg;Xkq)zwvOY;2&}(}9nl*AXk6L{HyoFvhU5vT|7v1dA-okR*xa^Z7FpbvmUa5x+Y1OiB>)5zs=MougiJ1+6WwY4=gHa4PK@44?hVMmi8@CoU=D$G!@wY3GShap^=L#b{X2m10@ z&n_7S#P06yyH=~!aMt6jM_MtX%EaAUrYSh0en(>Y1KRyIoa!IIQ2%*U${9ERlE#EA|+nOZ}Sdl>J2yu_f-k7Rrn5_KL;CX@F` zj-{cYfh{gBGG2holXvKL zj1ND@#GC7oMGIcMnkfta^5QgId$>3{* ze^{whg4JrZPS6`MxN($ zfj|IE4Fy;cS$cyT*N#J5o50ie-Eg>ju(A@nnayUOQLuvslitsFc6Nq)dwXTK+l_cU zj#MgzOeTX?Z#QNZw-7C!#;Lw@AcP>9Ob&1yCrXk8K@doxP&hBpuE!h>2g2bnTrL;< zen03_K%at^mKH=J5zNia!Rd4&7z|=_a}&8-&Z>zCC2JfpB7y)(LieI{&0(l4=b%t3Dn*7w`;kx*auv>`)3D6J)nbUM*n-6rY{NcvxB$V8a7@*RZ=L^f5ifi zud7IK2idrK**&p5KU+&y>QLZq$nFq)OAwv5eohX$&YuRo_ewiIZ}U3o(0MaKQ72s_A300000NkvXXu0mjfhN@V) literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/camera_edit.png b/base/resources.pk3dir/gfx/icon16/camera_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..b5015b103aae138c81088270f9f11da15bcad8ac GIT binary patch literal 872 zcmV-u1DE`XP)gnzR}dAN!lccO`E2gRvSvH)rF`K)PSFY3td^OAd0KH5V99U5f`EqDcV&x zMR6f^BgHTE1J(~|N}8%wscm1=(3dp-m*hR?MORf<4%``LxaZz;?ww0CO~d~zPTvLw z1}+r}g+QrPT2rZ1NU>Pt^ZC4>pQ@@7Q4|%c)jARih0g2#Jv}{J>G5@FXlR-A_xGDw zmQDKoe&}o{plZ<%qd0MRBb1pz+<4LolcNpO)1P`}S-wfZCTcqM9jwRWiL|%3TOAGu zW@l$1NfHu?1lGG+@$B6aV(CtFY~2My2o@F=jxY=(8Vm+-97k4GR(5kVYm3QbLL?G_ z-EN1^=L3}jDh2iR^@v8J7#kad&1OR&5WwQ%B9h5u)h8B^Js{#1jMVXFUy z)3c{iscL&{vWy*WH^f{7ott>rw{%01?tm3E6jF_lUcANKSuaqVMJ|`C1|Y#;u#fij zGQEfvi-k1R$fWP|K9q?aHtS1R>;eThU}p3+Lid-|#k5+Tf!{Oqh^!u_dsp{rN6!r+ zHhcl|-(EpWA28sjN(nz}>M6Mxz&V;}e-eUODhLu)h9a yaBR0V-`VWowzs*V@x@p9_|mCESHd&@8t0!9oOz=HFLpWr0000D;+3^E$z4{$MYU~w{WF-|B0J{Ada(M245 zM5B?xRH<4DOwsYEL^vFoOr=tHX|O<{NFU%@T3P}kw@ic3zAP5Kq0fOcC&R$^&w90dyv`v)9HVCDVj?z;#J8&v)1#8j&)P*@IG zl|zUOWi=QUpz#kgwRGSCYTsBsga!vU78>(_w3lYQgq=;Lm~?kll}x< zsTfRnC<;VuXxc_Wst3z_yv0nfuLV zGo~m?i>7Hrk|ax`(Xg^p*L7mE*<`2F`Eqh{a)RZLjg1Y_V>2F)@0022=@UH9m!r`r zm>LQ&Bf0h(x3Bj>{`L%y-}b}d9Y8vr884MePbk)oS&!K&zg1I2=eM67YCDh(scw zt$?Wo8K(oRKQpcS=llS9qiX2 z96<5lIf8nff>aqj?g6Z}Kc^((5rJ^1fI14R(E?SsgQF9&+wOqp6+l<9sH!;W?889U zFltQ^pGV$9`s({jz^bpWuOr$W!CJ)wNuXoWWn3E^hej1?x<*Ykuv5t*(sKz1asw+; z9QsN>1XjILshHz&l}Z@y?KRE$NF_7y_hJSLRiWw%6iq=@s^Oe}1P4kTA4V4-(3wtb zZEZcEN^Bh+9b|cVnJ|LxTTQ5%3a=wT!J0{yt8ByB-i6id0v0!xAS|6)Apd$yH=hRe zCN)>4tuO;a?m==fIEqi(iDiyMZh}+n{@4V; nyF}D;{j00000NkvXXu0mjf57}={ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/camera_link.png b/base/resources.pk3dir/gfx/icon16/camera_link.png new file mode 100644 index 0000000000000000000000000000000000000000..d2ac9f9350ba1b79b64d454dd8bbdc21c718cb62 GIT binary patch literal 839 zcmV-N1GxN&P)jCRQ2LkQkC`7#N(`Wzd0W z)SBREOthvcHI*MJr3DJ5rS$iC&Lt3>eaX4^y_fTy`!1#sw(C4`CBTT>a|!bh(@DuI-T(Q z{h(Grt-#@MAQp>Zb#)bXyB)z`5WBm(I6OQQIq`Vhr*dK@lR-;M3#w)ho_{EzSd-8o zeg;X0+wIq2J3c1*YhacPOe7L$Yikp&%DfbdMRas@;LVQ;%9;$LjzTY^F6;35k68fs z_xA<3QmKFhzF?_x0a9B;p{^&O0#zo3NFs@rilzrmNCbm9kKcJ047kd9Rem(BaR#O$ zGKC^bI5{~HIhPrn7r0&vrlN&H0oiO8;cyrm8yh@jnf^D_m6eq+eQi}v`g*-y@9U9~kyi3WgY0VK*4RXJq0rgcDLhfD z)efjVITDGa|0&?}`4sBePbV&ufDQsFOqK4&Bigsgt;@9QNVhs^ktIfBe*xE3qL_Mp RB%c5P002ovPDHLkV1lB^g8={l literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/camera_small.png b/base/resources.pk3dir/gfx/icon16/camera_small.png new file mode 100644 index 0000000000000000000000000000000000000000..454b0b0199df99a52603dc9d50fb108f138a36b5 GIT binary patch literal 489 zcmV4nF=aJh$b&b^ONN^wktaAf>FK-e!dO}leb)%S#D|82Kh z)M_Sl@!Vs?A}E~6 zxJaeYXf%+^<k76bVRR$kAvNPi6?SJ&zf9ynYGbI1cmq98A08I9RXOOm1)s zwryjvSh%L`L77Dy0Syt1$78SeE5LL*g=w0&Jh31V2O_bN3HMFS^-G}e*;M)Q6>s#cP zI`Y#S($G6W`W@NI5g|L-MKl0Zmu$m^(0~^Lwo5OO~d#(vPfz1rk%1hOvQ!2cN2d2?-uHXIEo8vToeK|KINWnNa4+Xt#u)Ykn|6RndSZEQHfCZG5CcC=T z`(o_NTOjbCK|GPF4%)<=%>`agEOIe^kJ+gSd~H}=`AYZIyJS-%Y|LeBxc&DE@kHvV zh>Ui%*7I#PNlilw1y@n@6l>qJC^2jm6{4Z3p@!y54^361Eu)pbu{`o1V_kbZ`MR$y zdh}&Y@Fjlr^zxZmgL6TIkJ-*qG#j-x`OjkRipD3485n}nXu!{oDbIFDjcz9A?M5% z2PG>yimcp1&>5MK%jHlg6reM+k&%A@^fo!tWxH|QR0Ma}26yDTXd(nZ3#(s)-0F2- zez{50^fbdT&}y|H>u{>mC3+bKC)$uY9*^5a08#oQKc4{{)TYPG8KIs|3 z4ORT?V0lH~l?0j&3hB7!W2DOBEbhsYf_b7(V%tAvUOfK}hzhb~cin-F00000 LNkvXXu0mjfWpp$z literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/car_delete.png b/base/resources.pk3dir/gfx/icon16/car_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..2803b567847e69fe64b0691dd30dc83d5cb8e61b GIT binary patch literal 689 zcmV;i0#5yjP)O%0M7oPLI-^+QP?|IL8KS>CIorH`X z#{U;kx03cgzm1lD&iP@kbCb?=Y=W5?V_7}Rrs(-_;>oo){}iC`H#cZ?N9}vbmIR%1 zFb>LqUnCTbuQtCJ{X9Zj;%93SH5XfYC4n}U-rJ%075Y!Dm1|o2KLgO>T-6vG~ zU~R__Y6#D#b0=pEa*kw>#ikhTYrejO78!u~M-2O{7X0h`!Spj`&?4f`5S^I6JW_j*t8PJ zvW&#i3M5M{M0yFvsP|eYai!-03M21;xEHWkv7}aG!u?@3_kw}O#>S}A=@c%POHdx# zsv8(Pr*i&jP~^wYdlkZ{=g+|{pU>AvYnt#p|5xdXh_44m_7@FzBa>dhI@OYE3e_<$ zZRa+6J1Xy+_7vT%DrKrF&msApA(l||?1t!-wtJm@9S82DmgjFPx>RjABG%JZH+%FO X1fWDOL6s`T00000NkvXXu0mjfK8`i% literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/cart.png b/base/resources.pk3dir/gfx/icon16/cart.png new file mode 100644 index 0000000000000000000000000000000000000000..1baf7b9fde1195da75a09a4ac8a7cdcc11542c3a GIT binary patch literal 421 zcmV;W0b2fvP)|9mIxVK*qV(LJCr#hETgDW!z&|9$wh3`VrtfF?un9PlRLs>2y(-4 zrLKn+LM$+c2R9RpV`rECN`sK@HGt)oU|=2}GdOWzXOuyDL72-1pjr{L%5=%8 zRQ(pEyJS{6KMcTc^`djdIyOcaz(RmDeoTeB8zvcNthS*`>A=K4->m8f9c)wTh(V)x P00000NkvXXu0mjfbTF;3 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/cart_add.png b/base/resources.pk3dir/gfx/icon16/cart_add.png new file mode 100644 index 0000000000000000000000000000000000000000..45c2900089c5b3867019ddf2d1c9c41552d66b32 GIT binary patch literal 711 zcmV;&0yzDNP)uCxwbv=KH9zoUDon>V zr>UxI+l z#KOV?tXAtCMJ|^E)z;P)Ha0epPNyNuGGeh9*4Njuva*6;Fo-}P0FTGRu}4QoI5;?f z$z&=kve_(-kB`yqcK=$PP6rN$<5RocMzvanBuNc}!7!r8WHP+bYPFEh=h197LA^$! zfn+j?{r!DJA`y-Wg+eHo%iPh-%*WOJf!=_4JdR?q$TO(d>pTNeCUT`x=_#{;C=?2$j;X1sGkv$Py1I(P z!$Twz39zJva5zj#0@-C@2}IWEbb{S(Co+D!Mh2YN-Q7j4Rs)eqd1+}0rBaCoa%Hv( z_V)ImR4Tvy@g2C`Zb};S^YgG+ER-}@($Hu$P#T`&g=Gkj-rm5_>p@&oUYt1fLwX|J ze5DHBL!@j);j;`WIfC2L1zdi5R^$Me%XOaFdp9>XM@hqIG(xY}Q_`58p2l6>Rjidv zSo>h6-65tPLP|ZR0blt578bWNJ3BinisDB`9zE&c`pZjrU$*1q7cN?9zz+a>(-SOd zeqB2|JMjDcJn8ZAag2?P;mWgfcq8A3P9ElDU1GT3!LQP4wNR;4n4FyKbHIS=TjBtW t@&m3+C;j&_I88CIp4At!{qxjQ|2w4%;hGY8=Cl9+002ovPDHLkV1ip>OPc@y literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/cart_delete.png b/base/resources.pk3dir/gfx/icon16/cart_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..ac5bce5c8862ff091d89763a9c0ed19a70e639a5 GIT binary patch literal 742 zcmVy4^0M)9E7~PQm4Jv4X#i>2wOI zRH|*W+0?aK4YJwnF$x&tVRE%v1))#~tyT-vYBkjBbJSTCeRBEc-5YwfMssp)=!%M=N`K@UcJA@FCzC%1C**Ti`$vEb7M z#Ts?^`j+?NC4&`CzviI$={-Ftmv-4ojK||Q5M>V$A1;aO4mN*`U~|h0{MrYAk1s$V zk%C^Q=4}-zr;nG2V`{jav#X!KFy+1v0a22=1R0U3pl!)07)2~?QeZA!iu>VoZOn9222<0v z*_>{&&CTH?(D~_>E9czAE;OB+evM6@zV{=9K@6gc!wZM=Jmx!`m*JDd zXti1{0sD=&MB)B>h zj(dB1iPBK3)le#x=vNEzbD<6gv>$ulsz9%mV|S?@i=8F-(pG$_ppk5Ej^5pv75xEM zf{xusl6r}dvKW%*HQRYk?CI$_%_#l8tE&qNg#sGsBT%+y%-9~#(Hi_(tH2I3NvNX) z;nvG11Oh=ikAM+NOkTNME>t#DY%YGT$GlC3#7r6XqUG3{dx0foQL5o7FTsF?d_JGf zBVar&W^Bo>%S8OKyNa;p4kqi5!KW^T{q+?XI-6M=GqtF$u8#cmm?RPj8hPiC@pm9I zBgahBHJBbAPuc4(T&%6F74mpI0!G1WEW3Jyep_`W>ufH~I@+$gEu!-$3ti`La_RM5 T)9mKtTqbJf(rJ5aze{dD~bnS8HAT_H56d@9+Ejex4r>0Plb5p9Kbk0a~pV zy}i9qsZ`f^p->2<0)YU0J|8HG!sO&6#>dAoIywrw-42Vz0+Y!EywGFe(8k<{~On&vLD*(|1}rjW^GK@0DIP$=BL z>la2wMo=geFflO!mNehta1bZ{u+@ZwyEeU=v|z?wXYB9qCu02ejcl%#>FH@C5(yA7 zaWN(A3nlv*#Y@bUH#BJv}|>?(RmPstr-=WfYg4D1PX| z+JXy_p_>rgY1sMeBE7X;+V{qM(XjH)iemNw=tpPqZPkhyZ4G3?>tA;@7#J8h%94Jp zR;vkVbar+^BNre|HKVko2Qz;IbjKNNWg4-b8iS|n!uN>c+<{617FG*66$-^IsZ_cs z6}L68PA|W(;I5B}XC>>{C~{={N`xfU!b$^nr(4*yv@hRwsCqMf|CywvR-QL~~kw}D){QNqzvVhVWh2j#+V9D}J*-*~M zkb7aov*sg~Jpr=gtpqzxGl8~K4C}F8}}l literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/cart_go.png b/base/resources.pk3dir/gfx/icon16/cart_go.png new file mode 100644 index 0000000000000000000000000000000000000000..20ee0584f61fbc7a4759ccda9a3d805460bc70c8 GIT binary patch literal 763 zcmVaV?~72n$)U z(3)sy@M190gjOOI`b?=sg7TQhow?pSp#)+iF`neiNzTl7zwe&&jl>wk|AggV0r7a8 zX_^K~DR{jhC6h^0f?*iYb^TC^j}E2)`u%?N_xEFMZ4FaXQ;QaHg>X1*0*(q*RWUg^ zS?cNO@nkX?%*@QJ@&lh)1oQIpGOSiB3WWkZ9uKnFEPOtn*>7)e$I{Xgy1Kexx7$7W zd>-j^S{xXS#bOCdBodJli3DqEYQo0GMu@*4)oL}QC<@^+L$WNBa=C2QQmJJ2x3{;& zb&5h+op^}*H8(d46+|%GY&Ig8IU^CwPN$P}cXz|(a*<##D2RlDg1}0(HBL`Yvw?vD z@S&nose}YrFbi<8SPZSWUy>cViI9E=xm*rILqpQO0ufx&gH$Soj*bqKIS>fI;c%GD zZnvB8y};Xg0k7y|!M<-E>7bD&CMH;IU1{43FhhfCP^i4;aRt!py^Q(QH~3s2*riI{ zyZb+w^fxEojfdIQ;7#a^`@_&-fT6rufYW*sbKhQLA@`QbRBbe!I6gjpp0nQL?6(BF zNZF;D;OzQWXj}#5YBXKLPvsZ-d=YGEI~KAsE7$FrpI4pYu#Msyv^Lo9efwma(rkj6oIv4xraO`e2x4AjJ z%qz7ynhQf^4{kb_bA{+YnXnXn>q!`dZ29f?yO6Y;L=T4x=brERp5Nyj5dcxGQ1bWi zI@E|~{sy#ouKYZ$PITH2MX0eH`#OyGSr(6+m;b-PEAA$uU*3ZMY)6yhB7WyXp%8+> zAVx+;;C8#8i_+;dXe=%+VqswcYW_at++FBCJi)tF7QwU?FUIcRmiauc_16it<#HMO z`}<&7HZNLQT0*5#!QtVd5R$PQFnoN9@TwDRLIcw$Ifj${c*!;4y8c4t;NSpTTU&5A z9N%mNqCsDmrec@N#qc~Yyx(Xv)*m;Rot?${ z`ntfNSS(_GejbJG0vO9#w772{J5NkZU~O%Ux}&eJ?_AXuVzC%Xr4r`m=0Hd@@pzm% zF?3u4i=kqR#li#v0V>9cHIhPIHk(DEPyiKgZf+tR4r60ugEkbL{eC}kxg5H>x{hkz z0mpF|9UX<&>&4K}5G4&l8YYto27>{5y&luk)6i%%NB=yeTG83rd8WO+9ZIG0dsTz+ z@$suBA+hMg@DQUsAr>6%U9UW+EYZKlsm&;344G1h9{W_ga)!^XZ4iT&V zc2}#_DuqI^L&PenRQjW;0l8@%AuX(HWn~4Elam7J?(S}AwOSA{d_JFW#-tWvv3R>C t1GCvI!0PSoJu!hyCR0fy5-P@@`Cr&f$(>anrvU%}002ovPDHLkV1l9|S^WS2 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/cart_remove.png b/base/resources.pk3dir/gfx/icon16/cart_remove.png new file mode 100644 index 0000000000000000000000000000000000000000..360217b526d10a3a39e0acfbc4f4a41bbf986734 GIT binary patch literal 769 zcmV+c1OEJpP)m=n&zdgPnpxQq~{D&6m05<{G#c-_mW$Ue%e~ zz`fum33Dj^=QhnX%iLgNfhl_HBn(1)`Sv`|L0V3t!;c4k&+q&F{hrVB69EvFi`xFH z7oJ5bQ0uv#KCgzxxfgF1Zyk>$Uqiq264jO~!hacPgc?kIl3+0(K z-c3zSVSIcXcDo&;qoXfG$z&2V;_)~HLBM9;{6hg6B#Qgj` z2x)G1c9wSH=(q$HN5y)*o^v{#RE#s2%AkjZ4IA?xgLIFL@K zA(zWf%I?ABO=O&hm&d$z@ZEbC6 zX=(XcV&HPQZjTa>l6HF&*VMp~gzprfM$L=2nF#@3kB zqM@PTdszlLosPj$sZ?hs5R1i<#>Pe}#-I7$7+=lQ6LRxi00000NkvXXu0mjf3)^L| literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/cd.png b/base/resources.pk3dir/gfx/icon16/cd.png new file mode 100644 index 0000000000000000000000000000000000000000..ef4322357cbc34e0b5eeed34f9fdf553a1de2ee7 GIT binary patch literal 673 zcmV;S0$%-zP)fk+XBT$+GFLor|=G~7Z=&Bd_^zJLLP z{dbOmhNM(Q`mp7h`OloWYysF>=iU40Tf#?V356IC6~fPKul?5pw+W80zw#nVEgemD zincj})E^?AZGqXAKHDz@mch}3iwfqB3rPo#(gwa141DiTF(xO6U^eE%d{-hX0gf3o z8{W?(@4ZV6pRS)EXbxQZMi1!D!oC#YJOO&yAsn%9V=twmsxF*P_%ZxvD(XXc8T9DS zr0103x=g@fvEJ!1y5C7b$Hz+ryB7+I5>V>_sj5lWnV>%bWD?LRmBAb^h}fbg923Y3 zqK41OM-q_X|0W}n)p3}pGlwoCoNU0Ppf+VweFB8`9D=Abd!7lXx6+7Cma$90A4ue; zVKQTfc(bHa=}i!!qJ}b>M^UnvkNQWze=dVN?ZJ22Mf(14f#NRkt=PP(cyuKepkb#y3Gz>xmDvuMC zIuoRtGlX&@?9*%nGA0rvwq8W9jW)GLrXJl50KN-ci9ozQ$MNkH;k<IV|^+8goU4jB6C^%Mg5h>3Q7RCr>7r_DEKw7k44$|vUmJAm;${=2wBT`(Pek9N? z+*$Z3+nYyu(=ufrbdbTWW%|!LE6aD^rgi=em@XcV9q^{200000NkvXX Hu0mjf|3D;c literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/cd_add.png b/base/resources.pk3dir/gfx/icon16/cd_add.png new file mode 100644 index 0000000000000000000000000000000000000000..b0254effa6c39214d063f84c2fab1ee1d95e162d GIT binary patch literal 758 zcmV|(^b7zP# z!cC-!Ea4|iEcUm)J+YH85|w#Z1iq+@Uy_1&;Q+DB9_;QYSgfJxJY>*Fo_n+CN42IR zCIj!+^O*7E@hzjEM4}qOVobxdO_Qd9kp*%UXjg&MQ%gC#SlNY;t3jo2G(fJ^;|&v| zWXtF>3^75HVOb8N zKuK|`Ca?<#@hXIf%;G#VkTzobG_!~aN`6KrYvBS5CW!6^34f{#D{ZRzdrrd}D>9AL zGB7QOFgj8gb0o38b=1K7y9l#O#_P2#k%6bpfakZfFfJsuhB3*R zao^OB+arCrI(!ZzGo!5~Xq&jQRe~S_(IODe6FI=YQ-&{5hUwE=44JRvqi-C1f`h?+ z7ncnu(K~pNZ?&;Ptr4k5KeK=<34DzJ_D~fcHWXZYbRM(br)23(`QX^Zktqx=R22ncUklHj|3B2M=Ej;gbFYo^Us{nc2wR$w1%nAHOrh o-8

    KW+XXJr$4Vwmaw01yHP87~i4a89>F#IhBV5<>KCsArFP3K~RSeQz_oh zrI?6k*^{KApkgXVk^-S;4JgBj@Sw>K?8r1a`rf5|ZHA$}k_wFus<@|IkY8-U*BsRpdG@9y&yGjX7CO zRCctKfax%N^+W$kflmurzBfKVdsYF@&%^o!7_P?t=(b_5@!*3LlXbabFe1f$%Lewv zJo8<3M4wv7behz6@+!rFc0Q4XdIW~77uwr|twv@m3tG=Wo%M<3f3Nec#*f;@*$N|c$wIj1 mc!64Lo@-XPV$E{ddh!>bnF*|Cn{Vd;0000)-`2Y0@ls8H{BED@;Y7( znup@NACB`ak|8Ccyr61IqqG|#8v$ljh-ERZgsAI#V$}67;fm$a<(oXv@@w_=5VH{= zFNcJ@Cz7RpAk1WVP1IsfVd)Gry^PU8KyC?nW)!-v0`kghjNT^mYZ=yf-V>sxJH&_= zrUEc9nULwEiKHPY0h+WD%|TpfTU!&e3UInSF<$j8N94ECdGiRVkB`yEZLGY# z!T0M2d2;bo@8&jUWov@6N57(A_rn(tv`^>wFqYxd*?lC%%(F_U+6fQJ2|YSW%Zbv3 zEe9zi+vN&DubA7Wbgbj6G`Uhn+q%7(!Yg`r7ahln^=(Jl8`t?M9kfs7u#RMCawf5z z-ox^XOCYB7EfY(E=V}qH6-C~E{!ETpjd6d*Sc8Gu`wU*$kFTnn#oHygFYlnUvN&g} xD7s_%kKbA0sJ(W+zvX19Pqi&0&nvUi{{g(`2CeVNupIyZ002ovPDHLkV1nU5V<`Xt literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/cd_edit.png b/base/resources.pk3dir/gfx/icon16/cd_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..b0dc194b0525e847fbbe1241e93959a2f645c623 GIT binary patch literal 790 zcmV+x1L^#UP)-<$VlrT{=eK4py~mkA9q zM}&zO;URR)cG5pTu#nIa%IK^g^MN?lA~H6Ty9f%~_%Rm%v*mmWj|t?0N4kt2?5P<9 z<3PVHfj(yf(}E0%oK%9@m=E(k5IGRgGJ~if`y|P`b5cZyISPlUB18XZL0sLp=R~ww z0s6Q^sD42~rzL{r$iCC?tOVV71m10AGuWh8l2)0K$uI$x#b$ROqw@_r<9I(AMw>AV zR}fg)1T4!*I?fJ+9e^i+@P-~sU1eAqXaM)&8Z@sTjxzzy;TQ4Qv_%3ubQ3%V=i=!3 z5s7`-MRgx~-|hFXZuAxdQfF=sD~EhW25AmR?DXlEX66x>cCR$r0@|0T{bnsoKi zsQU%vKZ6KOyh7U5kG*vhxR2GDLjj$EhgQD{jXnh1>XCq@uc%ybJ%gGyA?>>l!S(=) zomFslRHLS;JC;2Hw;qGm5XuIBwTpC-8L+gUziW<0T~DA&7NoqDkOJjMEYxA;Qwe@^ z9NUCDyhQV=1P2cU(ts}kaCSQLOl>as4kZ6=#OI&F(|QvYJBP9T#?l^^QK8cCRHLOB zU^Wk7Ve}ED{S(q!6?Os@5GfOnt{C5@yzp!(M`g@!q%f6BKiUoVa2*`q-ymo$MQW`a z0{0m1wi5K4Jh1td ziw3gwEvyY!(OYvK(=&Fk0sHST@Ji4tFZ40?%caa8P5Q(0zkne2A0MmR4NNf_{a-Q?Lv zlXvM;av~}SDyB3_``6^JfkOrKJf+7H^|ViC(*KLFUZ5!dWWXp~#4k-8B?I}mDHLMq zJkxJeL{k@{r9ckn%M`oElqxuqmnGw=qF7W01(jQxeOcDG^wD6#r!lsw@hJg2NANak z$#PCepFmO!3@IgZ4yLetu_q2?5DLe1rr!J%gCx#ZNfv_!b8EXwaHyDnvxg-~PN$Qv z+8N;==Y(U1iieazYAf+uW==9D$>U=3e$P_D1L4Lc2jdeHc)ebR9*r=!o|Y=JN|U-W zaC(zCJV%Up4q4wXH+VcbiO=W5Fbq5%5BKd43B{}{gHY&u28Z{slsx-EmyIl<%2wsO zTrT{6KbB>&wY5bilVM?DfxEUI>g`M6t4;Lp=Ljbuo`pSA&|zj~hK-F4ve_*0c$`Qi zLNpph*L9R}b8|CSZOlt+lG3B?3 zhK9y$*+J5zU11H@BzbwK$l{kX=EFH=gIQb~7Ec2v>#=b=Hb(yb}@(&i(Y~tii#p5jVyfeAt}w2NTp(hoN0nO=D^FGowjKJbAceN z67Z(Wjp|-EIvhTDNfaPhjcJ&6A!H$dV+EHV^5Y@3rrCwk_9+-$0R-tEHIM@H^-u^W z2hhhMB4Ba&q0xyjiSwdby%(x4A_k`+k6?mc9%_AzV2}j_m{;z-p5|BEE1{^_j>0B8 z`mDh32|#D^&~#?um<0q1kZ35*IlxWS&#wu`0t`lr3+lE>3J{?BD&RdYp|W+532cnl zZDx4LG)AK_O##NSIT$Sxs~cE=_`~{#dKOSf=2sNbY4)(dbM zXPsdhaWO#ED1d92Kz@S_T|>(Q?vx$Jqnb;&P_PGOoeuPd1sDt?PH>Gj*<3;CCNYQ< z?J?Zd97dA*01}G#+@w}dAAbEhE%9^dAOyGM@-II3i!w^Zlj;JMxZ_VRZITUgms+KGy zYENT#MwBx;O%bu|C|lh@e5VndE7*=RFSjC2xe>8X*Wqf(5pd0!NYKQSd9(XO*1h#B zUM7A-!cUtI{o}LfF}rXuHwxF(C$TGi(_~zBM%1#~xWaX2@H^5YyxZ=t#)dS-nsEI; XafIoi2i@$300000NkvXXu0mjfN6%>) literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/chart_bar.png b/base/resources.pk3dir/gfx/icon16/chart_bar.png new file mode 100644 index 0000000000000000000000000000000000000000..9051fbc609b92b15af9be410e368b7adc20283b8 GIT binary patch literal 541 zcmV+&0^V&qIn(Wzh!))n z^W^$!aM&X3bCX~Vo|JLOLCb!-`g!yN7b-yh!|sbVZ|M~fElQAyiB?lO%sjz z7TJ==TTk%_A{ znxkIa+E~RC#EKF{U0G~y<6)R9(uCp7&f7|JN}RHwEO@{EgbF~D3a1<@ip|9yZb^6$ fo@6A$W#9P^w2GuX0-m@}00000NkvXXu0mjfB69Bi literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/chart_bar_add.png b/base/resources.pk3dir/gfx/icon16/chart_bar_add.png new file mode 100644 index 0000000000000000000000000000000000000000..d283e846a29f929681435f01c961faf486f274a6 GIT binary patch literal 626 zcmV-&0*(ENP)v?QT{`n=t5=RT+5AJm{BbjCAW=lY$)Da?%jsp?V9`R99QPKcuTq)0YGwL-(m(ExjR zzuclKmIO;e`|<-qG<-6WDBZP8-RFN8Ox*-kikvBOrm?96F3M(~{l;?gmI5KBPtkOY!&7>tk<7nGEZ-Y!L3%G}C~r6|OhNInrl zqM|;42>1ZrLyRHVOl)v{XpDkl^VKAerZ3ijA_ypt(BA64R z80Y(Hh{E@82W;)EvAMI#{Pa^6UeD0o(N$jIQP(YWX%`EErHrMF_GXrsb|5O2g|h>< zS^xBg@!?5ceO{!qsIvO;9rd3>6eoS>vAY)*fLY))&;S3R-CpH1QEovYWmCYySByZom|YEI8%B`R1GhlckjSpUF2{PTyTgQ57!`qvAzz zqRdR~&DsJuuN>Roji{mtBqkobY_#vd1jR>XWmO0<(brXB&1n08mJz%tHYgGkF7Kde zWOG2edbw;-l@x>&gkty#&L?b01W`Jxk%o=`a4>!xRLNo_i;?DA#Yw`rNQlr?O*FQO zkb;nj!0T5a0S+Bz&3J533SUOB+cLz2Edb7!0B0cx1Yy-BTu_WtLQM456m2ONpPWm< z3*HBU4LBFb)jB#vz&Z#4yl1VYSf4On@v-dUl-%R=%v0j>7o=XtjZSd8_KjT4`eo<9 zdk{fPC>^W=_I0Z3g&_JCdpTCl)!obD|BB)W!1_yo3B|7_u;pC;i{dA52tYEI|a~eRQO%X$#2w7ptC!l0{32(CI}(lp$fzNf0TbdAIVWCque*=#U*c zs1=bX}|=>LcQ-(oKM)02%@YgMyfV)Z*0?hzBX{Wscn$j;|pZ= z;eni|cI*UIvKYx?Wa*~jBw<`6L?{&#Z+D%ewDO(PUH#kW=o{kSd#^D4^yxlMECXt z;eukEvaaP<_LisV?B9i}oT9lkil($nchFpz>AmAK$4E1Yk|LY`8%?Z1>mPePa^Zn`}{-!`% zaM+rqkm?3Rz&fywnYjs0?3*RhOXb#=D3;p7YJMBP#nj+F<`s-Hc=4FJqo8#IA;6Zc zFuaYa{0^@Te?-fJOU#U2W^#OiU(QZ2`on&fiY3b318nRm6U5_;BRjhDc+wywC!`Q* z89Ku!AAAgj$mCCFnECwyUrZn4kA+^k%ReJQi4uvTXjHP463=>ndzX2$|Hb^RSNljs kcg4)j9~}97>MsA`39(pz6}>#e>i_@%07*qoM6N<$f^l1B*8l(j literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/chart_bar_error.png b/base/resources.pk3dir/gfx/icon16/chart_bar_error.png new file mode 100644 index 0000000000000000000000000000000000000000..bdacea5e5e1657df6b370a33720220fde962ce6f GIT binary patch literal 671 zcmV;Q0$}}#P)k7dBh(1Fmof__N_LYSE8EF!#ZI!fu@I4kQj}7N4aJOW zC{yma4U+MF|Mzy@b1Xh-%A_f$PN&Y|cb@0eQ!z9Cr<%uF9ys^KvMNy^XC;afL^-u* zPGwwx5S8`aEr=>=AlbM$I5K_(E-5i9Uw#NF8`CB=QFA(eK-~#Z6rU8yMrbbh>11qx z9o*aaqAHdIOF}t+KOq`E8A+7tgv^M~|4^{07gVX_OeJT2K2m}hE@V=MuE~!$y6P$~ zuf3nOp!dx1Xh2~}Km-N{VBijjP;(KVlrkz=N)|U?W_8a>G^KriTL_Vg2m}vFAPGN$ z5t8D9vbyyqbLOpJ>g;8_dwQ<_(B;1VccLVp2q96Z4-ExAfcFq1wYuV?F~vTzta^ji z8Exc|OLQ#V#TMGxwxEx#i+1Acooe5?WVgJXjX+nDxt5LX5YEghr;YuCa04Iski*|+HKTue*r zS4_S^rHOkNh5$wV5HlCfrTxtVrpHL-aPJY*Bv=qEWh`aZ_1$OV?&CBSuQB-!j81Gp z)1)pwKYhrVlP9Q*73bT>mVdRZEvAO4j%xceQN_&e{Q^Z5f`6;uX>b4l002ovPDHLk FV1mc4Ec5^X literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/chart_bar_link.png b/base/resources.pk3dir/gfx/icon16/chart_bar_link.png new file mode 100644 index 0000000000000000000000000000000000000000..bf18aed48b8ea9db86bb7621d1c9c63cdd121c41 GIT binary patch literal 712 zcmV;(0yq7MP)2BUt+C1Pcjhr)VWuX(u*z zK_L=?WW}hUEchaBuF0-qHhUlEo^$3{tc8V2z$u5}oB#ir@tkw~Px*gpUbirwvXUqKy|(sUy)2ZG=@>OFgmwP;g)bMDVP|vzFyqK^aG^ zEZRa_)=~eP1*Z+3G4P@UM#Hx4G~$#*3sKs%khFT3SpNl}(k4J9pbcoll5!|5#7fZC z(Vi0|6wXbYbUHPpsYWLnr8K@Iii|OkDA1ZDiYSCLc;&C`Dy*gaX^}{VX-!jlW;Rh= zUu3bih~Jar>C$6-iGOWY3au0mUccecmVS;MJ3$zR3=Di>V)7XW`(X6&C|N&C5CoJ; zCCoeUB}yPoA&!}u{M^zCfUtm#;TFHsCy!|pxw zyn4-a5CE|J@-7)q7#|-epU*cBEDXuup`S<42XmD#cvnWQInf5E40ZK`N}RLq zBa83f%q*uO+hkn-px3iWUBhj*zEtZ=#J?K1BwoS4fri4we+W?%x_!2UEjG9A57v+ddMu0 zbbp6n;=LcDNq6gD2L9C2J@8#y?*rTbgTj6Ps|^D5|MCj{`@<*H#t`wKg(3XGf2QyU zf0@G{{9_BdAC4aSKNVGeAq>dh`~N>9tN(u{wmT>x9B`-HYmvir?8JeOFVbz5u> zH|V#x^ai*A`gyzm|72hZ`OUy04pZPY)6&ahrsWHdS>_MiW?QUvoolwwWxnYbrv=9G zAbFr`rQinWXqscE(MN|a!$l4~hCDEFhknBjyGi=*G17r<_V)jl zB|4H8rP?#iOLZRs>9-bTIvMExwy4+UuxQe`XV#)U8P$NSZU2ojH2n=T)ZNqrEM0*# zI5i4uc*w#O3aL7Q*+%*5QW{Y@8K%V=Ja7ZFGq?QL&e;54D`OK7Z~U*7wgHIO|JMZJ s)OG(gKsaSB6tDTOk-Qp=;RaBG0e_Hjj63iYg#Z8m07*qoM6N<$g46R|L;wH) literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/chart_curve_add.png b/base/resources.pk3dir/gfx/icon16/chart_curve_add.png new file mode 100644 index 0000000000000000000000000000000000000000..f9e2050460f240983415928fdebdbb94111818f5 GIT binary patch literal 761 zcmVRLq zBa83f%q*uO+hkn-px3iWUBhj*zEtZ=#J?K1BwoS4fri4we+W?%x_!2UEjG9A57v+ddMu0 zbbp6n;=LcDNq6gD2L9C2J@8#y?*rTbgTj6Ps|^D5|MCj{`@<*H#t`wKg(3XGf2QyU zf0@G{{9_BdAC4aSKNVGeAq>dh`~N>9tN(u{wmT>x9B`-HYmvir?8;%0k4&7Bhd zEv?W0e`Jfprz!qw*Wd=|=k5OglYu4VHv@|}OtaTaOD~U^mM=VJnLmh{;(o1hb>jam zSEl~I@NC!r{@q#s!~1prn`cY*fEDZI?)*PTRKo$L*|EcDnq#NYM~5!MMGifNJhAOA z-#1>K@PFgANuaR$-?Jz6fB&9zkOAMp8g#R_|FB!KO=7K?Xn+=w@yEZBQ3BsxC{u^W@{txca_}{xL1#B~j r2JzuxKnw;d?f~LXAZJ7A4v;ti!dZAcanXRV00000NkvXXu0mjf_r!r> literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/chart_curve_delete.png b/base/resources.pk3dir/gfx/icon16/chart_curve_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..b411391c40582c6f465b9bb73e454efd7c0566f7 GIT binary patch literal 782 zcmV+p1M&QcP)RLq zBa83f%q*uO+hkn-px3iWUBhj*zEtZ=#J?K1BwoS4fri4we+W?%x_!2UEjG9A57v+ddMu0 zbbp6n;=LcDNq6gD2L9C2J@8#y?*rTbgTj6Ps|^D5|MCj{`@<*H#t`wKg(3XGf2QyU zf0@G{{9_BdAC4aSKNVGeAq>dh`~N>9tN(u{wmT>x9B`-HYmvir?8x@xqa?hX`q zy~l~=-%eNNN7oE_ufh$`&)fa~Cj(2!Zw3}|m}ak;mR=q+Enj%dGJnups(JZ*iN)XV zTYLZiySC&1*A+$oPiO1?+2zcV3s$U`yYv4XQ4I%}X2%YrX^x#nA04_37diA8^6YeB zzWWWR`Tr!}|NqMc|Nn1O{QtVk;XhFP9$15J_V)jlB|4H8rP?#iOLZRs>9-bTIvFqn zLC*encHMtu@V;K+KS&&6K-RYZMj4v^h8gN^>H(InKpLDHg*7~6K{U|MkH5@K{{J7S z=|>sE|93$AFoXF&Q2Ytl0PV~z|FttV|JTac1jHNvYo%=f;`RSEK{$2Y|FXE0|Ho3) z|352N{Qs(w_5a-z#{av0+5YcvWv(JR*BuF$tpM719~ujfL7GA005Pq04UpJhGXMYp M07*qoM6N<$g8Vm(7ytkO literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/chart_curve_edit.png b/base/resources.pk3dir/gfx/icon16/chart_curve_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..bd07673b55bef41b65858e7646f8117bb8e4ab71 GIT binary patch literal 822 zcmV-61Ihe}P)^(c>Y@u(F7)kFf>aU6kDVZZvH#RKW*PIV|R95O53!9 z$YjiEgA@hRg&A6E`h_sRzdDN0Tviqh`o z@ZI!-oUu<)OJPrt!|vdB$DogEN%o~PjHKPFtq2YWy~E?3H1p+fWU@wOXGI9af_jic zzW6 zZY)?sjpnY+HV&h0T@la&%RpzBLW^C31b-a}TXG?6%|dIE1)lpI04wkwXnwDjCRV4)Bpeg07*qoM6N<$f*6Q* AYXATM literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/chart_curve_error.png b/base/resources.pk3dir/gfx/icon16/chart_curve_error.png new file mode 100644 index 0000000000000000000000000000000000000000..906dd038368a493b9095ef94543ad9bb04e70232 GIT binary patch literal 837 zcmV-L1G@Z)P)RLq zBa83f%q*uO+hkn-px3nzYqrG@BROuk=6e{6WbkRr#t3u z?!CA!;Kz^GTmJue*7yJ2-L3yGFZ0}VX|X%&Z*l1ja0B%7cK`p$z!LJCfkhmq*>9GW z_tGV9-{0I^^Z&==rvHaJjQ{_7yXOD-dCvdN&2|h1x>gEqfL`v-|8qn&9N;#07){HW zWcl^}-s=B9UoHCo?M~wVL+ytDzdtPh|KZ-Y|EH!{T{}6^f){RpZua*7mL)op7Ny!V z%}aG3*_7$LJvhtp;d@}feSc8$|Ld&?2)-Q)^vZ<)4-ZcIf3(Y}4q-snw*N*Mn*N3v z>Tc=*mafO9+Z8-K)c61Ai|Jt7zut}pdcg=xf4i6U|J(D8{|`3nzB<^btpzqfJ9Eo_ z?TpR;wK6sV@y7oNGeW6fbe z=e;@7Zt(4JtNyn`&AQ)!Hhnu#ula3%t;RQ?rf+*IRln^mSN^uAOzAKH(R5;6} zkZVkmVHC$-#Z21FbTg-xit~aX%Eb$q*EvaZ1(tWr(}1B5w9p4)Z6!^N#9p zW|mWq&Ee>A7I3`(7L>gOKgj|ium;uAYtfOl=(vU-vGLeyJU7xbxXMlPUP(+|SvYt;shRIQJ!S8JnXYRoKP zmQH|a@GFIb%`+0TmSL}Aw9ltRrS~sYDKyMb-*r|P+|7{5w*)2QMuC2>n^Nn#Pakz; zOtVXfw%cdV6ZT}QM;(Q#pZRwpbh!!!WOdVsS_*AkLk(Is3+QKGLlvDLY_NC4Hg-GJ zBWdUbM1X>|05uQ@?8otQ?HPK}FBurZYL#6poWIJMoo`;VWas&^THM z7e_=O84`l@X&!V<)WNCSk>Fc{Y#0Ny!e_uK3v^|dQ?G}Y(-!dhE#pQ2+@EO$<@;vn znQnqxQ!-pq0P+bbh?I#ysz$!JS0eP^f`SoXiUW8Iu|LlKf4b|L0Jpym$)RXhX~@e`cKKoJe%3_!ppxsQO1LzUV= zR!=;5RXTy6s13+D{a_aS5BSP!9#sTzu0%+d{a@aHZ>`b{@k;;z002ovPDHLkV1gHd BcP;<` literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/chart_curve_link.png b/base/resources.pk3dir/gfx/icon16/chart_curve_link.png new file mode 100644 index 0000000000000000000000000000000000000000..144eafe08695598a02e1cbc54f470888fc5786b0 GIT binary patch literal 829 zcmV-D1H$}?P)Ma{BCQzS3CU@k3h0*+qU+C)VqBzQXSX@1qZ^5S>)?En1F?|pX;2>?jjfp}!K zj6sFfUA`>==f+sA*y4V=dFhj1Fyml8+4%{a%Krof<|SoroDj|oPV&EkCMQq~Gvu^3EJ$m|2AA1f(^6i3#GlX0T`T%|#mNgrf`vJL z>5AY!X4oQNYDXct&~WHr%d}Z}>E-G&BPXzu&3dr;BxW0S?^L@t%rbgIxt-o1yUQC{ z7cjIASS$WWWksgx1;NcPA8x>&r8Ig%$F!bD0mjLrE6i+oQqg7I5Ht=Gg3$g0eZj<} z(3z5Vfjw22CANB+ytmr>HonU9Gojkux+V;!rVj_G8T0D`n&tysqm^ccW8)*g;`Vit z9&-zx~ca)*si-N*Q)FlL&_3t4_+F3px6PF|u3e7z|Juo{v3vRa?Mn*>9 z`pv6Ln)Z6%m#Il2b2^=XI;cwsGOi3kZ^H3BI-Opk)oSNm6B8g+l!OEVK}4ZYfW=|~ zyUn$i-pifQ8pqalI>ryDctIUJ7PZnuNWhC2Lp&Z2BoYY$no%Y!6MaPj zrBdl51k}r~fm-(pQY(9*NOBQOce>$m-*Xrk7yzr)3L1?DbUGa|qYUj#=57#)L{nRS z4TVA>WinYMPCh;_q73a&2X%h~c-L>T2pyh000000NkvXX Hu0mjf(aLT? literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/chart_line.png b/base/resources.pk3dir/gfx/icon16/chart_line.png new file mode 100644 index 0000000000000000000000000000000000000000..85020f3205adc903896aae3ac8b2431d81d25a92 GIT binary patch literal 526 zcmV+p0`dKcP)vZ>%h3)%~ z#+IbJ;FFDG??-c+T_21rm1LV#4~LF)_b?ghyQZ9u#u#o3H=L6>&|AoXU?qv@1Je4>AlGSTjH9nQnv` zZj`d7z#wVmBfa>gsDTLdFI#`g-3Fu!5 z$Es7u?8}cWwJkZs2@EU)U|{|IH*L!Qck23oaHd4px(fwB|2_x$_YKg$rO1-+wT;%l zQ`7tXR!Mt3P6M2(&pepC=Hh>#e_xW77aS^%7ub~^eqd9yzkqI;iK+$w0LJvVLF}yV Q@Bjb+07*qoM6N<$f}^baNdN!< literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/chart_line_add.png b/base/resources.pk3dir/gfx/icon16/chart_line_add.png new file mode 100644 index 0000000000000000000000000000000000000000..5571a5ebc987ff07de879946160880c5482a09db GIT binary patch literal 655 zcmV;A0&x9_P)vZ>%h3)%~ z#+IbJ;FFDG??-c+T_21rm1LV#4~LF)_b?ghyQZ9u#u#o3H=L6>&|AoXU?qv@1Je4>AlGSTjH9nQnv` zZj`d7z#wVmBfa>gsDTLdFI#`gwkE^?tk-a$sPvRx(fwB|2_x$_YKg$rN}ONuWhvcotob7gjSb78!u1z zzwz3n{~*w_C-r~-o^+4_-x-{$&pepC=Hh>#e_!H?PM>PS|J$z2`Hu`XU789q;6H;y z#qk2W(!&pIiuM=aGQcuN`g`}Tr2p-^62O| literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/chart_line_delete.png b/base/resources.pk3dir/gfx/icon16/chart_line_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..5b0aa901297c4b1a1c2654fdad228e19d53cfc6d GIT binary patch literal 675 zcmV;U0$lxxP)vZ>%h3)%~ z#+IbJ;FFDG??-c+T_21rm1LV#4~LF)_b?ghyQZ9u#u#o3H=L6>&|AoXU?qv@1Je4>AlGSTjH9nQnv` zZj`d7z#wVmBfa>gsDTLdFI#`gTJ`Gy0&d=K|H zvHaWV%KQk3D^LOv=wAuPs#C}8%a1L!Ejh#q3@ig+VEz3!ZOZ>!cItmG7F+!MzP0!N zziT`Ge_c`Z|8%zQpIy!@xeTs#7Ycy>eGc^R8=!wnkzMp&+i3keHND^a9NE8o18V+1 z$@l;Na>4)q+Z6x5?sE9Q(}npSgH!dH2b0%a{15c+OI*;5By_w^G0LE;P! z6~_zgN)JD3p3giF1zAS%sxH4A}orI5s%T@qwybq0q#~{rhaR7ospkimCL{b0%002ov JPDHLkV1g1wP}u+g literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/chart_line_edit.png b/base/resources.pk3dir/gfx/icon16/chart_line_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..9cf660733d4271a2be337617957da5db7eb23b9a GIT binary patch literal 718 zcmV;<0x|uGP)vZ>%h3)%~ z#+IbJ;FFDG??-c+T_21rmp^v$%%xy#>Os{Qx#@uvUJ z4|MQ$Waqj#4p|Ns4d{QuWG@&CU+ivIuUTGjviGaX)>?R7Cg2}GcOB^;|x9kVY#w$!%d z5a;oHrLyOz%b}X%{(pZM_5b6Q>i>79I(@p?V`c(RiLP}Q3V{B74)pIEpnpq2g4>!U zgRku<{`vRYq5t3SC;$KPDE9vcpi6E~b^dmv$3g)mDLYl4c`$j+#s5J6z61%($&^jL zx~=N}#qAURKRFrt|Lgte|8Fl;{J%BD@#T$P3nh%a;81bAz^?T01Dm4#;J9AZ>HPoy zrw9LU%nJFxuS)9w(HWlq4>p-Rz0_f@LsVvJPSyVX^Z1niKTl5lf3nr_|Ed(3&pRvi z^oh=mp|*nG+v7EU@9psXy{Fgd;O25&C48wB06Lk&#h$7;IsgCw07*qoM6N<$g4-sJ AV*mgE literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/chart_line_error.png b/base/resources.pk3dir/gfx/icon16/chart_line_error.png new file mode 100644 index 0000000000000000000000000000000000000000..ff23c03a8a9ae7f2a852d5e98010f973f2159545 GIT binary patch literal 741 zcmVNon?^(g@=7(m0P4# zS@uF^lyA;-;f-`HKIhC0gH7U$R&h>oiG-F)j@?nX5Qkh@mGuYg&BrEfcmMRa+}OvH zW=p}!(PG2+bwl=g#z<4SE#Al|b*bb7bv+8nufO2(hu%bOV7nl>{MqIxzvRgtjHSX2){ z{16D5;Zy(lUctE2QuBZ)7Lb#wzzo$RCVpmh(>k7Jg0Nol*^$j_83$-p<9~)JTQ#dAXuGdH1!!Y8b2gkDmG9# z?4Bp!jI`hE|2~51tqZo89Ij7HE3wALeFZ_M@UbQE-tsFk0v__is&pgvkcPgNO&b@D zGTIxnRClFH>W@e;t)xHVuNtHkW|(;O0{p!#-HRp>?P+|MoI$|_+UF5R{H~x>AyR$< X=nrZU-jyx=00000NkvXXu0mjf=^vZ>%h3)%~ z#+IbJ;FFDG??-c+T_21rm1LV#4~LF)_b?ghyQZ9u#u#o3H=L6>&|AoXU?qv@1Je4>AlGSTjH9nQnv` zZj`d7z#wVmBfa>gsDTLdFI!hq-@bX#X+L@z8vo6kH}8K}amoKn){fuj1c#~B)YRMs ziM6)2zRSwWDz&q-<3{$cgk#0gf)Z9d-K|58&^ z|4*7U>3?Nq<$n;{+uQpONDgEONG*d?^_d5g*IfJ$^zTa}BcraSrl#*81N{B{x$N!j zKkwbU_y4(b=l&l$bm;%uwQK)_#6WT&13+pS94d|%*p(iBU{kceKv!2cGd(^1J;;Ed zprDL1_pvLhz$}0$$<<2sYMAyO(5{~^}XKP+xvdis#R~-ty}kh`t<4l z3kwVXS5#Dh*&s2H97qjFEs6nZYHG|tCmMKpdEHM*N%@kUo&6n%e};#L#{sc3ko^fH f29g7*0jUK58Cr#m=F_A89qTKGV%LqLqA&{k|D2>yV7qLmg~*x1@cbjz3zP!z2FhV16<-TNNz zuIz$fLNt0{xWmll%$dUkM1*+|PHJ2ZGvdmC35A3UoF6R(-~DS$BH+@Xy#VYsLyQ>z zxq>v8$ny|FSR~0W2u4ic`k5mcbEIiLksz4Y#KyE{9LLn}_oq&%6$}Oga?Zh83$3-^ zU4V1$eaMkz85m>bTh*c{3ch%tltQ=L4Q7$u>-Ff*JP6K)r(~Ul_41v6uR1rSij#*! zl14&E?hS3Iagod#Oo#p}d7WbijUO{Mqc5?@<$>unxw*22 z?bQuGkPsSMOgEm)qR1=cLLyZOm>T65_V?)|o0p=i_uUiST44Cz-W mqJp!8r`H!$*8T4x&4Leh&Epbde3h>N00007f4xW*L}=Ip56|I&4-dab0EEr-e;4KEPYQmU+1ds( z)h~nw3SOI6tu{|revn>V4-Z^i`bP8hcid+i94)>L52&|4lQPzbYAfu$^gKMU=@0?I zaU3kmq9>ryXb=Pep66lPHl}G(sZ=lw16|k2<#J>)8B|q8mSz3{T-T-7vy;grp))wM zFq}QTkm#J$k1#y9r*rW9_ADR>GfyT^AE%jmG{$6oq${VEhe%k5h~C>z!Z^U?`{UTH zGVi|nl@_$#rkj!04+E{ zDL6%BT11$vkMdx>in(@&)bdalI9wed|6-PG^DKiGcHy)Z`MYYXWh6yJklh61&N0U9 z7$dc47Z|wJPyfvbk?T9zt!|;NfGmsB6cK2ILwFr?K zNQYR|Rf-e`!QxO$i%|0Z+`sRhd)=afDXBfu zp)>e6SDClGd*5ov|+hA_DkBeX;yXW=}-67>L5X~ZT%Y7$(I4GO2nfa{NbKhVN3P6Pn{ z3dlK-`vagARySMF+Tc<#fY?|?vH1X6?m_@a;sE={gTX@lFk4#4pDaEu57{uxZ6o<< z@qI6#O!+5+UtxB1p6~D63y4)H@IO4TRBhX*zW{g%134O4{TKiM002ovPDHLkV1hlF B{lowO literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/chart_pie.png b/base/resources.pk3dir/gfx/icon16/chart_pie.png new file mode 100644 index 0000000000000000000000000000000000000000..fe00fa050a833fade14de445c554b21ff2266632 GIT binary patch literal 918 zcmV;H18Mw;P) z)5~v^RUF3g=bd?{7w4U(okA~6ODQu&AyTU)qaihDP=g^ZV5Kfhx?#trq@YHED?=nm z8X{F=Fli(%K&l}`AXu0%WX=(eO^E>Cfm*WCSBpMff|A0@P&0}b- z@vu|b_butF9--78p(rVogpgvCg!(S1p8cR&zh3^)8!?W*Wjq8aNzH zSpmoJP*=GgH>dKrnER?fW_*%Wj@zr0*Zui{_|PN3iC>TI+Zak*tPO9#w7Q3JJCC3a zV5jvo&RzX%snXq-j2JJCCKFaPcWV{5XYKvx54R5jK;Xmiqfw#6K%KP_V|Ed#`y;sT ztRPX@g88|-V2s`i>)nU8)Kx_5YbwyzXn{x#yz=&N6aWHTQcq{~E~`XS$nyzsS73cG z3QL6WP3FRQEO`2wAm>1$IgG-LK(wkHZA}qNaO(LBV0(k1a%AlSlq*pcu+U!h1V)QL zgVw}BN1A;dn&m(!J1{?U7yV-=mn2ht$Ch6^GqI93 ze+WNbT38m_O&H+JhxUC)WkQh%K3KqM@|PRK9ha^TE=rQe56?E8-@O!mOY_{s^E~~+ zrER?s(gWuj#5~m2gfP8eLrE$<02qDwZRYF#Q&Vl1x2yzvG^f0?x!E#`zrkO#K}6uf z191&uyJ(I-hT*FvIFc>{fH_#|IIB4w*PKo}@s=_t-U8qAV2))0#vr+bkRFJD&g~Ht zCg+jKWo*w;eE?u;o0&f2Z>pWiGPkB0;zk~!#wPeSgJuLNI7oO%#KI^Pr%}w^geyh& z?9h=#00@LWKC|erv2Np98pst8YG{N{93Bxo5>O($wzBNzVh zg|)61U)Dl=s^Xhk-THM1{5S%=@JIV|JKj0xDM_xYzV}>pVm|e*{jX;NfaR@ES)NqA sTB$w0a+2D0+Z&ca0*O=8=#zfKm;e9(07*qoM6N<$f`+80v;Y7A literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/chart_pie_add.png b/base/resources.pk3dir/gfx/icon16/chart_pie_add.png new file mode 100644 index 0000000000000000000000000000000000000000..bf0822ee1c2330582ac8d5d23bb055b7b26b1843 GIT binary patch literal 975 zcmV;=12FuFP)N-T$EI`5GE^Ew&>_I1R3ak8;ov#X^Zh>GbDrnv!rb(x_aE@u=jNli zuFL(7OunsKIn^bV+9j1}lFC9_azse=y;tpcx7d9t|HGG~CJ&_D2YM$Cw^>>B*^|Ys zRbF2KSKhr$%<^OE zGO6quHHDSjS-gp1h_?c6`~Jn=XHn$QsVmyT z$n4LEwA`1qd`BBL1-&ZkFu$UhU9c^6z3czOwQIRd?+Ek_ZFC9?w3D?8_xbdv}_5h=fLfX!S-a}Ro9Hq zJZ+9Xb9QSt(y}p47h%|xtn+hgDTA^^;vQg#&%c^D)qi9@_U-01ZioQ#2O2rOxm zOnptmmU?WDO?~-u*jkq6Z7l$Ac>EvtEjwwWL%TW(@oD_wavWh|3xO>pN=TCFMf{r1 z3$^e4!Z0uMmpslk)(%#EGiZ_dwg;Sx?_4%?L2(!x@Le^M(>d|{ZL^Bn;6 zoa^BF(gc9i9(?0!ZM|+=s@qj+m!q;xZZ20BPA*I~cShc+sCwkhmbzAA;q6>o{FUK} xOU%!$^*#jrU(KD79^iE#2&93&D<3T!{1?J?)wFqC(+U6p002ovPDHLkV1jg+)R_PP literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/chart_pie_delete.png b/base/resources.pk3dir/gfx/icon16/chart_pie_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..5ab9efd55489c87196fdb984644e6e06655d64b6 GIT binary patch literal 983 zcmV;|11S87P)v*Gz>VKO;FIU(QKXc3 z+_B_gom--t39*w2+QtM2<7}8R@slbx9jTO^-p_YO2%boJ3>+Olw3(aYn~jz2F;(-y zRBTlFS7Iuc!i98xX4%`R&(a)HWD>+;SgD4f zGdF%1KQ|gtPuybE+#9bAAf0CjRd~_3Ca5z)yZ-}>U8>uQWH}9Caa6c;G*_(0aOOH_ ziFKJ=JKnN3s0!0T?x8?tmZK&d0HbUd0BD4=4P3F{f`S(PIn;Y2_-8tcL^g3c7VKY5 zDQ}I0{kWMSAchTN$wpJe4bEr`05pRVTJ2lmX%D`Hx%@r!jT|j-LmWR;eB|5<1gF_YfI-jxIDWqGSg!H%x<$2H5}GpC*6K>;Hk?u!lu{68 zBR+K&+o#T8*}@$x_`(R8(IW6Jw83o4X-R0WB=m&Y5cQZ1Q8=~@Z6pa81~}n}q`t*Q z`)4%0vk%_bv!LTch+e(&>XmKoE|)ADno}yj#W%HjL}LteG7ZO|aLNX3gMu@H@YpG= z-_il!?O&jr*^On>gQ$;&RjJ7LUG6VV&O0Szk8&#kOr+tiSp|m@*p$Mi41zKQOEd7* z#DK1gKyLx~a2lGChUzHw8UXmu51cEtZ`q-arM|Ko>SIpz3V<+3#=!+eQ4I((df5}W z_#QZ&1p!c6QemseD^I?$*z|&KbI~J(*y#wfOqFL&e*vC^-G=ZLX@vj)002ovPDHLk FV1gBE&J+Lu literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/chart_pie_edit.png b/base/resources.pk3dir/gfx/icon16/chart_pie_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..3debc12d5ee0b8454165cf2ef52c976c414a16a4 GIT binary patch literal 986 zcmV<0110>4P)jsHp9U>bEUr=&5Gt!&3TRri2n1-U zTm;cl1%x@3A|OLSg|^f}FF-+{1yod0sQpVz1#)bOntA(hlJ~=VemUpK^H2a#-YZ+5 z>UBn&kdmt8w((kz%*HfD%pO)S+QMpr`3J9NE{MJIWa0n+d-UOvsY~$@YEBN_9;ij5 zr3s4R26VjC;)=E$gp4MQDIeuJ;f|#dW&KxiT+0XdQ7UTs z{>9!)JFSe8;vXYR&DPS^ad0mWf)MF~J^)0W$%{{`Pms;S%@7$SV5y@Ku8PL_o>E9# z#MmL-#$jI=l4jSAL17?KaOVYRX&vNt-owT70C!)3qW>0(Oqan_Mg z#Xg;^LgUY2;=b9NIy~ovh$~egSD-cx? z32ORpTMp!z?q@5Wp;}{ur1Ba}@(?_}Aw*Y+KXm!tVU(lw;jSB&I>cy_Akycdvabf` z>P6Tj__c(Q+e>%%byO-RQCwYyv1T4@`dWZ|ib;Jn+A{;5Q^K#)ZOZ3rTA; z?@OPI4RMNCV&ycGndA(nTc>DyR`W7)%vK{GbB+ga3?75kJ*Qq-1eDT)GwQscpD4SE z{J4I(RJI|W^}UPzSJrfBC`qOy<8{bBjAnXsCJYIfbGBn@fC=Xa1NNRo=<{hH7zxGm zL!9~h#G*IHjuyIDEZ1wH0FxCmSmk9HWNyJ&2k)IZ49?;Gcx6mNw#aC-<>w{Ej2yhi??9k?7RKdx(!2B zqCWt;1*Reb&56tLupkh%{LQXE>D=?*P=#J!JtmJPR;}?89P*xXwM*bqN7bJfg$X9H)NvVL#5#asQu*UTQh1&55X+otlN8~^|S07*qo IM6N<$f|4H26951J literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/chart_pie_error.png b/base/resources.pk3dir/gfx/icon16/chart_pie_error.png new file mode 100644 index 0000000000000000000000000000000000000000..7344174fe9ace47ea4f47bd3202ff9cdddb2d8ae GIT binary patch literal 989 zcmV<310wv1P)ZI*IfwoU}x-gg-1~(b99V%+GpGGY8 z8^{uU$6!iFWSvjuhK=!Aj?@%GQLY!1(0xw?gl=S#2?r!Z)J&dX}_ZNc=!eVprSpJN*DI5EHfY;rNK z{JLiC-2$!qnbPnM)X)Ben+q?2aRr=E82}VrC--{q^h9p_-8I7qJ9%WX^h(p5_bs6( zk~{VIZs-2(c_n3AkX>Al8rKI%`|9xEVIepp=_eC3@@@CPwL|S=;rg5Dnqbq6d&np+ z``D7@z(SoB-j;hi&zI+i_4qrK*T0FK>JJ!6jlp2#djL?n(vb^7CntqY&KTkHEF)YF z+p?hC9>h`=-VW8iDuebRcBvcN4!(~((hKjRNlhca0{|Q%qbc@M<_)$rn#HRsK$63- zH3HqQ!xf6W?90(%vwMKBVP$$zvAYe2YGSk3n>#50IGmrKow1j+1JbQHkQj!us2CQ> zU~ZEMe<%W5AAqn4qAeR>^9i`!DXiPv5;PfqcU22ZjeDLGlzz#>YbzG3B{-X&MbUZ> ztV|3-aKx|OLA0eBlDr1+ynsK?AA2ZldyllT#`)?x)nfecXlwS-jR!Ah$&L{Sa~^qdNE1k7nZ!vgDnzZR{ZF7F-cgf}WVh* zAu>`9<<2tvIX{h?Q`hp+kSow_~4Io9a|l>H+{N+gjmJ6ISs{@ zvEQ`^U;g^Znlszc;+CEpZK-v6r~cW*zYFHkfwQ{@0YH9#{G68w)?e=0io0e6zpUTE zdS(N)&Ja?IaS%e^*6l-YY%eeLR+JQ?&hG-HqW|z)x4i%$Tby<`dsz1}^#;-R)iDL|i(5|Ai}a z8)NDZdVO^1K5JAV!6JFs`8>E#At+NGEU@U`zs=lk8oD>Q%qf5G>_Twh(3*b2wx;Hu zw#J?rYB&SNbFeHMl;q$maUii|LU0;=01*1cHxoDdF3#6|yM06Hro@{0(J0er-9_*Q zgA;qBKV>$S9bjoUYUmJl_{$MbE@PKxeYLfA{-8*y}cc6ZEY}3liFe<3;@N&#hMBL&Km>Q)8S_idrA7* zREgII0GB;($eb1Q^z=a2bpQY%1hOotilPhxKq8S~(xY$eXxP=PS5XqtvlD1?fN3S_g{wRk)(4-XG7J_gj+*DHR%zfsrqLBlZ0G)+?g$SW%= rF9S%FmX;0zaB$9Z$z*bw5Yq7Zkp%;s8}r$h6cUMpt8KZ&`memftw9r2BH zXZp!+CFaEnJk?xA$eKJbHrNPn>;Axd{TeCT;zL2Z2lqOE#$fse--k~9GCAnb$WrIY zUzF=05;%7ScRp;-^ba=g4+!_yjOVxZHrAy=-Qy;3W{V_ws3i3@rj zN6Uq**d4Ifp5hMksmBf!JrmJQC(GkeNV1GOW##ZtQFwF|H80+P{}RL%{YNk_%ft(I z#;Cz`v~ti@ZP83cwQ@*mu2Dwn=d>z@4RV(M%#h6&LDo!N4vuc zo|;?G=MQ0U0&vMd?WX`v6t{tSSteePbgELlMO}xKy8^QHBD{2ALkbX%5TpZC;3a)d zD?(MwgLzpdUa8!vFvP literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/clock_add.png b/base/resources.pk3dir/gfx/icon16/clock_add.png new file mode 100644 index 0000000000000000000000000000000000000000..598b839b818bd0178517bdd88669bd8f9897a5f6 GIT binary patch literal 925 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 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/clock_link.png b/base/resources.pk3dir/gfx/icon16/clock_link.png new file mode 100644 index 0000000000000000000000000000000000000000..481cf04c12df9c3a81e58f2b660566059d55eae5 GIT binary patch literal 961 zcmV;y13vtTP)=R~W}{mY5~mvTuu@_L=O9S(e2Z7eNN1X^TnY65PZkMq2E!Myv#IPD|MoT56%$ ziZCq#3bD0~B5HgoEtjrXkwUE?RZ5qlvz1m_+VWC_|IRsa&2I9$dG2$b|L@#;aybB8 z>K69_K}qlu9uYpI{r^LH8{enx)0?|Yg zbBPrEp#-|`O~W`8#MK*3@b+w3o^1crL$W#SAdX+Wsj0U3(C!SvM0TUs+jtz$U%kc> zsVT{I;C%ly42~B#W#aKuhwC?X2K2VCZPZb9&4=@M{Fo#=r&rgJOsDaOu>%nzT3B9& zyj@u+eBlL!%m_fgqlS6R2;{u%7BnBYsdc26A(AKW2jbs!pXq zc^yaEhH$7_i~zoPN$R2h(sba6MQ2#d`+0xF4aI$ zRRfRDhZCpkQCwUMi9`auUXR+^T2>21B8c}NN>YhJp@?Vy_05u|a^YS{MyaZ2f}_ng z ziy5>oEG$H6Y3U;>C@(LcXW{<-{?7=>fq?=nceM9W+x?0x=n};ZJH45VhjX-Vl@c$LMez8BK{Fk5J9h%Toeig^+qC6 z^g__y1W_;*DNWEus)9z4+SUg1)0oC4joIC7vYAb0XU;b}`+2c3_Q1J(AKvr697Ai3 zH*T1~Y2YLvK!56l7Va8v+-L?a0RixG>V%#HFp6K30Nzcsz4YRq_Sf$57eC9-uDbJI z+2<=j_l|yQp!}SfX=};ElTC)qzVjC_&~Q>O8@VqyWgQuO(>nBgYiV(G^Y-#w{QK4m zj+2b2OH={yLlfnD9M2Av4ng#OU5KV3IF5B}2ejooI)NtPq- z?`))DuZhNB!;ScDc8#zuMrz|c_j;p}*q)wF>e35_)|$7^U3@>*aQLl`W`_pRJbS#I zqU%!deA-%D0H|pAe0+hbqsiu1DR}YsK7QqqQzpP_rS-w8hU%8$zOE+96-^?MVB))P zDY-782$v>)Ak(!UH}B({`*2nAQGhsr_+EEK8MsoVsi_W$G%4HW&e9SSmw#gFkLx_~ zVS6n{=fPHP-MB_}Wreg9iQQRe ze;78NIdl1Ua|bY0+A3qjt1M>AM1~2bMehTB#7u)sCPPphzK4|c^OQp@1yvu|8^`1Rql9jVO^rWPyq`j(K*<%v~I4%{UU zM2JGsN-0BY{XYQU!&i^ptgo-P^Mzt`dh}*&#;`GC7Eh;ZfG`X(tBR_Q43XNODWz(F zv9YlH Bw}b!y literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/clock_play.png b/base/resources.pk3dir/gfx/icon16/clock_play.png new file mode 100644 index 0000000000000000000000000000000000000000..fb4ebc850a94b2c8c59502f38230ac54f164dc7c GIT binary patch literal 943 zcmV;g15o^lP)GE3cNY&!T;=j^f;gxRLSB zG&}X{iKV^(TLqKq((nH^HB^n^chQay$`D@KFoIjnHWarF`VjOrt_N+()gGrw;^Es) zekWfGF_*F4W6rycY4)M|Xov1W$d9~teRyOXfP(u9xvB$sk2`Shbq^GVew4gr@kzaP zX59LCdg%EwGkF7;F9pnouEP1|#-f#;Y_{cdNG`6*NqK5QVM8yJbeph7olboIHi!w*0{lB+uni}?Wrdw+^I36lWz9>_zB+Q!R?Y#*eJ+7IfA?SK}c<`81b)DS%WfNkkdw7agekd(LJt;LA} zdbHK;#S3jCdh9L?O#>;7i74;R$JJH|5^G}+nRTnh9}srxzBoes97%U|kSfg>rh$!m z0rw0++Cc#)*?5$g^H5Ak8dDIh+>J>2=C!_n&;)r9(Xr)x6+{IbvXosg^g6)PJa~^6 zM$(5Xqmkbs!zIIM{D^?Dr7 zWwB4O8@cTnIMbzn`GdXciH?#bSZFs>;4sc(r;{{_Ow*WTd* Ro>>3@002ovPDHLkV1hPn!1DkA literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/clock_red.png b/base/resources.pk3dir/gfx/icon16/clock_red.png new file mode 100644 index 0000000000000000000000000000000000000000..2842cc3386709236ba7608965c716054c08ecfe0 GIT binary patch literal 889 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 Z`4?5=&N;mrg`ofd002ovPDHLkV1fozjIRIy literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/cog_edit.png b/base/resources.pk3dir/gfx/icon16/cog_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..47b75a456a4bb1487dac02c60b7e2e9cb5e210a6 GIT binary patch literal 865 zcmV-n1D^beP)GR@vSHz5C(pPxHny(nM!6aSI^7R#-{J~?A^0H*YCdW>wX><0M=1!YHEsWHk&65 z2EzpTxW}DK*f^ce)R~!?WFk%?;`Pu5C{Y@ z9*YwPJjH96dcf=xJG z*kl}##L?N=83%;ar!Pg^cVqOf0lN#g5Vlp~vzQCln=Feu@%+Ain zAxsXvy}hQ%p)0kKIRWUX89RYeM1w`x^47xBl|kR;=6}n}%d;PbNXFDkg2d$HB$&Tm z{utC0|DU)7(XWO0;TB^4`9-wVaC#H&fkYyy8yXslc|4xD*f81w?^q4!T|J^pT>J`N z!zOX^g^2B+#!yvN6)P_<|3AiofdL_tJahBjw(;Om)xxQMf{?WUJ4;0fJMO^QaUmuX zzldkm(9nR~++1P8J!ouf?5?h^rbixT09(uOy~>BS_9Toi+4ykpEG-e7Pv>wrR8CF~ z&1SQ^k9z?Ck8E=Xrk5^E*cXKych#SXij`csx@x zGc!|URR8Z@-ez@mRk*aYR7k)D1f1O3+Cn0cfYE47n$6~dk&%%?lgT7JmVkge2$-9n zpJ&`|cahWSWTMe1B9RCPkQp8xE+RzCz`y|4+uPfbN3gQ8A`gedNTpH;g+d_UJ)6yz z4Fm%4`~4Ui8p;yz9;plr!(e=T98FD4@*DwCRS>UPNT$c> zo?c&Hhu7h@aN6V&1tPx8*gZ6@Cpc++uq*h z%caUBNc8pfL9JGoQH984W#PvAo3T{LfK|&gzA{=34Ob$Oa01d}ZgX>!_ec+@0!bWg zZEZY3$Xrps^HGnZy)XhpB3Q?|L8|5NS5;MU0@4z1Yinz~tE(%$yu8el&>VC+oqM!b zUL6>`@#Ao36o+40kdBOD!6?DqJJo5CNE9zGFZbp`ByG}=Ao-x^>hZYYdRL3xpb>|0 z6`ap5;#bOuW!+V@D=SQS@4#R%DEj;RvukT>Jeao2=Q7}vRgO%u2W+?sPHhPeVp4pM znlagO1$C0!>KuVyub0#0>B}QT(5O{=_V(-eMuI!|d>{K8qCYcqi&%MqnBx`RKD=zn zdk0FTvZJ=PmaD0$VVtk8J&HM7koo$CSKkj+5(}mL%0|UtnPE5^&TTuC#b@(A6Cn_a z#p1%bmzNUkZUmXM6^BWZLDKNgG~wu{ABkB#Z1U5FW51~DdFk%7wj^U$U*M)x=Q;b+ v;*9-?keyPTVF`$}%1*IX=}Fe|;KcNA$#nLD6jKLZ00000NkvXXu0mjfo}8uk literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/cog_go.png b/base/resources.pk3dir/gfx/icon16/cog_go.png new file mode 100644 index 0000000000000000000000000000000000000000..3262767cda95a217ac8d3fabf6c4bfe3514fd770 GIT binary patch literal 859 zcmV-h1El-)HU~Z@BQ7|ITsWqFPt%czwZJk^u%JZL0Ogu z7-JwwQn0tTclx3}?kvID+L{XidsxQ^&e&|W7P?hu`JbU6)Keq zD2hUaNxZkB72a$%4^2)^`UtC|A7te-nGAX1Xrjep5qO>_@7ffX%SGn`-ED7gLpU5( zk(@u5K{Og2Z)$29rKuELp-_NyIt_Job>MI~K&R7bgynLX>`sh~jA#lt3}_YQwqglZ ztJPR4mEiF3kO&v?|I7ONdO%xaZnyg`4MVH2u&{85WF^F8xkx0!oK7d7&*!07ENT-s zHZ~xYO7;1CzImGB_xm6GXq~MiVV0C|gzZGQ)-QC?rN*&h*fy7fxUu2>pgCsM)-Q?tMb$Vds z*E@*sEW?$R-d!Zlo`yI#H#gqa);3B?D6pBWXVBO67?`R6Qy3_qLZ+|_MxhlJx8`9r z{Xs@mdTouNQ0N7+J#TJqhNGh+O#w+J@OC~45~`3D2_z=L-&zrFU%dy%Qdzg0ic~cM z%s{~na19L&^isj*=4PpCtqL-e!E)J#V5X7%DWt(#}Pq3W$oGSy^Pc4j%jrk7_ z4xV5*S(C}slXQfB*Dx$m5ut)=uA6Vdoof#vmX1Pr{o_H2ueAT3P;2Ktrs3gX7h2gv zE62G1jK||?p|odbXLH|f%y4eoeRKHd`|tRw^&nXM?`u5!c)i}iTrM|2E9N*Z__gcJ lE2dmBR}@y4olxbIzJJd{=EC=vF*^VN002ovPDHLkV1lGDi4On( literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/coins.png b/base/resources.pk3dir/gfx/icon16/coins.png new file mode 100644 index 0000000000000000000000000000000000000000..0ca9074d66e7a008dbdd265a48ff37f454941be9 GIT binary patch literal 732 zcmV<20wev2P)7$(F5I~EPw2+A2=20Sy*#|n7r8sf)7*RgqMLv3&KWmL+^F4r z7i0Z}>kq&FSJ~Z9+<5!dQFwCOz1ndvw%m_4J#=sT@Q1U19`B}1iL1?~3va{ZF~|VI zfHw0WI@T{zdi2I_>3m@YYk3d;l(JU>d+bPFLOo8G;T$3)1!qp*$dock%HEEk|V0 z3L2&;r~p>tQh+yD{T!MxBF4;%7xC6JH1CtlE}+w%Xkuu&haUcdHC?=ZKr(+GZJfIQ zJ6@GU%>XYSae67{=&NN{rB<>+N;FbBA#_{A0WZW7cXJ0E=}(_?dx9< zr?bEW55s(NboZ^^cb|S1s~AxnBh?-gQ{Ob@*3}OO`vCi&FRqICO$~lSg*6r5QDf7DTmJy^bFNy&p3d3; O0000Fn@9 z6}_p-po(}ZBq}nQNbG73P@(2?NiZt6&X~)Q>%%i4kr8qQ=3COEo>Z8 z*gxJ~L9Bf2mp|AW?4AJafQ|B5v`GBm0)<^C(Vi8&d>zzaGr9rvL%;kwm?qdJ*cN`F zOcqt~+Pr7&1#Vw8>eV~{)UEe zBiv}!KK=I6or}I0!A1+%jcFuZMU#K=`u1Z}C8^y<qlji`q{QWr=E3G!ag_G z_nO;N#PJ=nv_`o0C*ktKkBxus*Q*bvceNp!u2=KJyN6kimuW;5e!ersP&@v~d3bGL zL=5kUl{40IL=1Ccby6%>#?RN60G7VkIr73|1VIEh)s6TUxDXWT zs&peQbYX%;a3Ml#B!N_onSc(OOp=+*$GtQ6-rw(iyA+ctc;M^~59e`ImCZ?K$0t?v zp(>*);;E3R=sd!;{%=9RgLFV+mBTn)0(Z^)#jt!uQqRedPJ=Z z_@5kt?prW*$m+P^HpIy1o3}jyVnLD$PPPHs#dek;aj|Br?*BYcZ1W$omHSB2M&brR z@i1cGBOeHEI7Tq|C7LWFK_8-mHL?|u%XCHG#2bU3EBl4g;}&n{Nfsg9Y@goGG15*HQ0<^0KM#w90$_`+XUOjFN}~y z>v--w+G$~<7J)N@&3Y(U14x9LHfV|@tB`guM#v3KqWLN|tg$+~LFF&Q;_X1JrxoDl z(J6Do7bDnc0lV=ONmtP14c_1cHdT_^b2N@vd)6STjdAGA&xEA|PG@#%&-|n5>rc)W zCS02-PEf=vl<@n%z#sSq)M7Fv9NtH6`!3%6U1jpSQ{)#P;{0-&zVbcB_ZFSFW`6Xo z5ggYgix<%DJ2YJ(96NzY?~z4o*m@OH7xJSeIC1g4`_)}Yo4~gjzjfATPUW|Kg#^Q( z<;X&i|^ZNRWr#pPVFRH$(hHl`Jc@d3urM&Fn54lrL`PX7e3_ppL@2%x)G0ch8 zX|dcoc)q>_uylL4RGZ7+*(k3aAtI**(xB))9@w8d`yYJHm@9=_7d-#~002ovPDHLk FV1nt|Z+QR! literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/color_swatch.png b/base/resources.pk3dir/gfx/icon16/color_swatch.png new file mode 100644 index 0000000000000000000000000000000000000000..6e6e85212b85b7ba0918570c2ebede3047596237 GIT binary patch literal 209 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmUzPnffIy#(?lOI#yL zg7ec#$`gxH85~pclTsBta}(23gHjVyDhp4h+5iLZjC;k_h{kHThqfC`(hFmxSO zSd?`bB$R({-*5T0gITA{|Fu6pn0eqpx>}JTL$UWimE@yNe}L98c)I$ztaD0e0sx43 BPNV<; literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/color_wheel.png b/base/resources.pk3dir/gfx/icon16/color_wheel.png new file mode 100644 index 0000000000000000000000000000000000000000..809fb00e5aa1f28726db3e2a5adf8f536bfbcbf1 GIT binary patch literal 892 zcmV-?1B3jDP)n`HO=N{yXhvI{h!_0ot^nS)JXfldwbvK_6nsG2Z&Wi&v@PQ zheULFT39nvnw}fe2u3u2dsOe=oVI#j9M1QC>zmd3XI9C7d+1ER`oBP|zA^0tJC|RwkIug^e1fA zX~N2H7aFgMFJ&|`u{>vFkyaX=K50U-_$2WeLXrR?y%y9osP$m;9(wLDa(L0IUjO100%{ufD~Y>02&pjbm4v#?whc82VKwMSB#SqZE`$mB-jcCHlU+0 z5!eC}fZ@6i#^osNm{8QAUxQqp!Je3uR3kxXnuJ~O)qerH3OWj$UL38Ff>!fEx(x_D ze9vUyrvmBUlf}BOj>p;pw*yU}8i3vdQv(|vr;&lW3vL^{HjGO;yJh@AvLL%V=8X-d zj-N^keq9GM0OdgtfE|S-5NpMdyD8XjL8D3d)Ci3ms|*JAHOZR#{F@d3_1R~2nP^IO zx1jHVVL;UcM?t(JNH>#EYr=^m)YgmC{@kfR@+(bUGOoFIyidRT#pP%sAgjUt2GomC z-GbUC?3chRN8#8QO)J9o??pQO=z9z5hjj@+!++`xv!lb9;ml&Wvph&Nw86?bNyh%=cqNQD8i+$LPB!e5mg zGpxOzX7}R-bs>C2a6nYto*kyOG|b@Xj8Ib}DhS31*TztPJc)IANu4e{-2WFIIaS?u SuzCdm00004%P)i2vikyMR~)n*keF9=!Gc_n*K2@qsNT?}H4v4a974 z1ArVJApZ0B-@pGKzWw|E^3%Wn&p!V9|K$C@{}12&`+x7vzyG&i{r!LE6~yrB1;;^# zm?0Y=moxPMSn>r>N00000NkvXX Hu0mjf$^yWL literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/comment_add.png b/base/resources.pk3dir/gfx/icon16/comment_add.png new file mode 100644 index 0000000000000000000000000000000000000000..75e78dede2c9cc3b789b880e5cfc930e60bf2c91 GIT binary patch literal 530 zcmV+t0`2{YP)~sR==D{nWel_pb&wQ zmrP)tTX!KGk)Sk|wtZaUrliFMw8)@DB*yUg%5WWG5T6(V4-98P2Jan%`$mH2CMxfq z+T@bruYw${Wles0MWFb|;3xR>p5Y`0A6-c}5Tk;D`5i8(NGiA>_&gYcZy8+IQP@fF zZXmTF{tLW(AMNV7m2gb(;iZIqf*k=ah{%H8=`Ai$Cv75^d>yNTn3+NncKU5>gAg(yWFU6q^MCd-9z5C;@-l1LJzY$X{vI4G2|m$FQQvK%ZWWD8>- zgBiw>v1GpI?|EmK(9D?Pt^eVDzka{xd6!QHK=zl&{!Nfkrw-)wa9%lZ5e+BOkzk~6 zb`NhB39iQI(vgtta};&~Py9F*i3oR3gsTUF{+^(_C7hTDhu4ICg9NR?Ca>sR5R#a$ zg0P~t8SBSO2K9G@Glq|E2nQeV&ZUGcy-m>2zaj()4h827pPD{kBVq5#25&OFu5&K1 zZ$Y$w#8tIM3A+q$Ur5+scugk+7OSALdr=5t9Uh{Pd>x{jwKK^o{&9%j&aTn&d1W2y zExSmgD!@cq5T@eg7*6z|mh?c)uMdeO+6$8zUDcUbEs4eRSQBVl4RdcXmJ6d%lj=Y1 z3T|p2-xQrZ4kh`~6T?s?0c8O|Z8(gLap+Sj$Qc~LIppMuxoDeKhQFQ7ZB;NPdEKq| zKERb8J8}SqUP@&!aZd6*F{tz+w*;+OA#)3PQP7u#!%*&pgIo_xCCgEt;yds5U)P)+ mI@7OINTTfluFUYPSbql#9Qmg?vhGv>0000+d`M13jj6(1&OTfK) zg!qUPVgGHUxLV}I1}ul#Fzc;Br`N~2tN2UM;u$wjO|KGs%@7Q_4glGCOy56_G3R!? z>v7<%+Ya@+0M}rU362yLEYfg7Cb)5SH?+V#Xxtre9s4nKZWn?f-mEDouwH?+FD?;tGeKp(!2F0zvT?C)LP^6Ev*qJN7M`JO$ro7H zs9RU)9gY7Ht*ot^&vZXZDa)Ugf&)Yg1xe0XL6y?}uVE_`?(Q9lvEUEN#mz=NKU_+g eqns}GFZ~5YF8XjkorNI)0000kO-!8JjERGZgNx4o8zwI5pnrkJT^AW7B+k01lLkoCLBu@bfRhnJSkT}{ z5cwz-C?AEk;`Q7|NyO0V@Jst%?>X<@)8|?6hNplZoH}p}R=_wBd4A);huvr*D{8ta zv>weaRZy(zA{a{x)NMK$oUyoq;&Q_jA9Yid>V_!Q3{lkDazCTg+2GL8fKO$yVv7pZ zw#ZdlB3o|B^q?JFdAt+nq80!As0d}1Z|KFR(*lEh^G}{es&~_I}wY;n4d5jAs0d}gj@(+ z%6*K*29I(Myv%_UPWDD&5qS@s3~ZAJGDH vT*SlN0ce3)r#d%-F%SaNZe6;L@E^Vb!Ji3~dec0&00000NkvXXu0mjflI-*P literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/comments_add.png b/base/resources.pk3dir/gfx/icon16/comments_add.png new file mode 100644 index 0000000000000000000000000000000000000000..b32563442dac029c917d2904a9b18699286228fa GIT binary patch literal 648 zcmV;30(bq1P)+T3bY=D1?}_NlY?Ho5{==PS1UvlqjYh_;~Z)+;i@`X96ce<835NqD^>4 z&XOGf0{;@=hx@N*ld4p4l~reDjUrhpR@CV9f@0l`W(F}47g(HMcGd5)tFmQBWlN4) zva0$#ktvJ8U{eF>D&mYUS}ayos$i>R-q!og44#*4SLN7QiqjOoolCvH@_0Ib%9!*{ z6Iog3kb+N=+>-pnU?fMOHjgh#DFJzSa zr=~gCYkDH){NQL{E?_QTF5oToImZ%%?|Kft>?cE#_{4{V%E1ld`g*!OkTk8$ZoV> zKJX^+zklnS93z%haS*(H5Yf4Nh<wEBWegKV6 z>~o(OY$)C;Hz4-DOD#^Xc?KafsKud);N~}=u!W3~T`atL)M&$9vr~7LRrWkLHXNZ5 i7Wa^nT-#rJc;A#1+9e&U9~QBdhb7i%XEvtC8q~e*9 zTGor!c}UBO!Tp8?(pAKoEsCX!Dv~OwaI#?S|7Y+#Qz)whJ4xaq8BjDPqnKjt1re<^tvd-qJefSYq(anuCjd93vneh6K+h(i&yD!a1MnYqE;KZ-O};W0OdWKgI_pLK zle)Hr=PlJ{;*D|xQkXchK9;-N1yEG%b|6WX&N<<4bB3E4Y$IN>=XK}S-Z!3BGt%RR zcEyG7o^?>|EvvpZ=hdbo)D!63ewiH?<=TAz5V4&90#T#$5FJ5q1^@s607*qoM6N<$ Eg00gme*gdg literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/compress.png b/base/resources.pk3dir/gfx/icon16/compress.png new file mode 100644 index 0000000000000000000000000000000000000000..8606ff0fd23c97d71d43afa0bd587e47c1e90441 GIT binary patch literal 766 zcmVZcJ%1+b$|lEg|m$p?$2s-?aFIU^lhS4 zt=5>B*onJiX5((A#g&zdZ;7N+zyNUJY~v8{(NtqH{`+@8xk&m zG`u_jq?FJb9n=hw%`FbbD_m;*4&fCDuR=V`pUsP7fU1Tp7Q?_nK-IQ85K85YX7gRJ zgwtoomKC%RWTO%Skh+*{%b>T>VfXA~9;mZE6vn=~?YHE7)8Zq;mfF}l;^WAReVKbv2dyl8I zZdsNM9oTISwn$ahzw_tMS*<#q^{;+1adq)i5#6)A{L5!4^#~!-uOE5i^$%Jv0}EmF z8*kM!$D7UP9;w~?<@c-q)vuj615`xxpt}~#kmfz_<a!u4Ek1OWvhNg%r^rdTXsY3VK8?SdPP#w89em&*t9`8-y> z{{XWmi9uo#0y2mREC>R)tyU|D<2Xwun+7u3ce~yHC8N{n5>SE*7ca{{mxCuK52M#x z6?VgqVUHr69iApkt_fp7}UIJIX)^0!0b=W3KH zu#9)c?;$B!KqeOeo#x5*?d$d(>1am)Y%kbK4HaZEF7DqvCglmk2%DRMFl4hCO2bI^ zX=T@9j!era3Mj9K%ggW14jP4g$@9D^u1>q%4oF>&Q{%YG^bC$1Iv|Sn?VXTj+j1A` z_4;iBxjK9L%sJ01;N^>_f2ih9=zM1B|Mb6I%0_FShXA!&ZGuYnYi{m5Mm>)<#Bd!= zpw*3PwK}@fZ5>`FlHMWvu(WdP)7sBGH8?p(}ako9KYX(!NC_${+66f zCL^323pYiGbgW{=R3}SA9sZ^M67CqjK_%js%5CkR;me zO?bAIxNg3Ro($a-cu31+pwdB9n{8&kSIhHe>aHBjVXA_CRI@ z^iBXW91h1XCKo*~ZXPqvsnh6OjES;@0=+mMNtWPHly!FDxdig|gWCPa(Ea&26soIrWMt?>>7bAgsH$4Y)5&Bq8mV)C%YB7Y+Jw5j^+Hk8>AUFv z&`yo)gA$EKn@UpK+S;xY$oZXByDL@Ihu$X-O`7@r?DzRA6X`K2l^#WNxC<>WFJptl zO&yXgxs)7>#kLY#ED||;DijJqRXu2EXxy03=c9(D--^EXGrJ@OqsiBFdd$}K z%S6%_$lmt!JU(1H|HXST8NZXhS$l1}(mg$J6&O${e1)u?zBm5_@-L-Nh&J@-00000 LNkvXXu0mjfve9f* literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/computer_delete.png b/base/resources.pk3dir/gfx/icon16/computer_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..5e9b26836cea5f91bc94770592555da48addc64d GIT binary patch literal 775 zcmV+i1Ni)jP)IB7 zSr<&xRLO(9u(h={_FdAy0EUK!3MrvO*Y&f3KmiO&g5y9$Q%*Rnqqp}J)W0Ps5{YA+ zTvAd}77B$hJ~0JmcN`av>kyC&o4^difI2!lYS^~zClf(Ane0=k)bElpKc6BX2ZxUw z7vEG)E-$Y@I=vv+U4C3v=?dc);zUun5HFrTLsj)o!Os7L0!HQJ=8iapNsuI(y-9es z%;F+$U)e1f2jlO+YD-U^_7t#GX63+eQ88p$hD0W3jn@p|Iv!*7_8PHvvwI-30(vI^ z8H%E;Gdb&d@a8e&oHmZmbX1fj6qwoeNU{V)RrBn^a|z_V&UuWTpW3mMv4jc%z!Pr> zm%xmXO$DNUZ%CM4u*7P0pc^%V?Wpaag{2o`$?Tx6NFIQkt&?r+^PlIUHWP#Y%SY5* zYC<4Vg_YqxjJ$n~vQ*du@cC5Sy1YZQ$22W0FB?L#-|wR`Tr9LUW80ZV1jk~)n;R%7 z)Umaq5|d*Is8rXTSggM;cTmU|X_^+{?j(~*gVY6Tf6O4bIRcz$%BxaaN}(A)vFM9Y|u11$~II*CeXV}4Kt5h{aWbSmSRg)zoxZBrQl+iPQ*@N>AMLYl{sL3^s-3vtl?VU;002ovPDHLk FV1kc^U#9>7 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/computer_edit.png b/base/resources.pk3dir/gfx/icon16/computer_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..34c72fe521f38a62bafe480939dae2f09359741f GIT binary patch literal 792 zcmV+z1LypSP)XJ>QW+#knvSxsA!iY&~)5F#Wfv4?&j69V6gpqF|Hdgwi*2U&^A2P1m( zwG?87QWFXzm)SH{C0BiLH?ek|m1O5Yw!w`uF@yv8xr+$drk02h8dkA3A>-Bayoi1nu1j_>3O)x&67t!cDh*w%b$)ad_`wt0-nYz z$gd87mrOX^^$_z(O43yqS3?&~1nYXtlPyu*Z^3uEo$G?JCw z2)JvCWu%kCA)@!zDOMiCFp*msLv@*jK+|RDKL;U5Hu7pc(i30sBX}EzP{CBw^hHw3 zzVY!7?WIPs*QV;*&xB;du0eX{DSQD5`OG1tCS#a&UB!`x<4j?&x{5X1uDj6R-+w=( z4M%R=eTn&@2S_b{g0rp}TWhK@wbktSr8#%Hlp1Nmxt+TZiA1VM86ykHb?Dzm5Nh!m{6#539VR9^r70wOi!1tM(B7`KwUjX#i+jVe(%oN_dd__z0W&E2!a2tNF?$& zm&=_uO;e`~$}+OqEa#`nzW`#fSQ!=cdA;7##lLh8M%buc7~~I2w(1 zak0<+Y>&vtW;+D$sO&gI#7))$ATa zU9cUVsuuX2&+zGCJO62`{m0})2F$%Zu9IWL51X?cO%H%7| zR(Dg4EnSfS%*c)6m`dblL7~2!sU1V0^AxZa!Nik(?7egoMJr!Wj0OVmZz^y&blkbP zTiRoqIi%BM&uRjdst0Z(P3%ds(}uP35j6*|A^qk)L~dVR0d?~3$jI9R>w`kM+~aoD z)QKT@+t0#Ik5la`T6-E`XJ@d@l|UeP7%M;D$zj{_U+C@ay-Fb6`|FiMenUlNy^~lc zNNyIBFXIFfgrb!J&SMyTa0^2-waE>Da5!8+*3ETvbYkuObu{+egQiZC)Rdgh%|&)Q z8!-Dhip1dU7aIVfP)H;B&3_5|}IFP3a~35lF6iQ+x8YRd8jCpeL9`~Q!*A8(?sN;y`xk9r!hDb z3S(($Sw4e=s0v(~wh>)=PJukHoMj>utihA_H!)**r3y*F z8yAFA;E2`R%VhpvvKL`GRDH)nFk+$7yAL&0O<2ukkpBLL2s5%Pl0Yrw$@Y0NKMUb{ z1MQJ>u&M91V}nO1wLFXcp`%zc)^YjSF*KOnd4iG>4c9N!$@ZA0g=|(w|CAxY-+oPz z5}FTEW7;NG^i|aDZpNCK#nAd4XjI8t@%Z!O#X%t-@OV7cIXef-wy?t+Ca^8Zek{)* zP+o<^>`RQNlBkYj-Wf>rcKbYZM2AS)kbX5rgT#l zih&_Q(57*Qd{Jm>qlr%5QJbsxdHT2&(JZQFM& z%TftJD8n>OfiIPR5oEL3ASLvKLZRE0l|C4h1lNU}O*!Fk2*bleP!CJaWHRj{IU0@D z*VNSD`}`7wy6bYd+$ACohsX@WfI2-rZ8(loK_MsY+7zg1+Cj@$U)PApMe<6A{HBWJ zc>Dwkg$=3B#l?k7Ek6x>`Bu!1&TuV(oLd>t<6n5 zxpz(~j;B9CxIKRDX32rDDpbY9aHJNDF(?$Q9O79JaK}Z1^AU*zL*8iwFZX~62hQ4Av_x<+*@a_)ES%MJ$$?c~9)&6JsOp}&L{S3ag+K;T-%kV^lPE3> zAs8SBbFUHF_Cggbq9LLLp_n-8ll7N|g5?bxO_5~;PhE$jPogRs$BvUj-K8cZH^xc? ztX!vv*{^@^i-u?bmNriUd2&=lMIaCC=qRr2lnA_D6^}bl%jK~w8@g_gD;L#P4&kjq zc&lBw_9U2F0GJ=#GBMLPhj+O+RO;l@(a{fWyBmct;`jR#wbm4TnBa9Cw-j!^hvIBu zVo-002ovPDHLkV1jNh BU;h9A literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/computer_link.png b/base/resources.pk3dir/gfx/icon16/computer_link.png new file mode 100644 index 0000000000000000000000000000000000000000..3859db214765ad84536acf95b7fb667570697ec5 GIT binary patch literal 792 zcmV+z1LypSP)5M>TH{B>uwY0wtGA0+Y*fG8|ORs-ktON{mwbxCmDu;|E*Xo_NZ2? zjaRExg*?a$J2*IC|5W-HKq8T_P{N$mYW1q>F;plCx(*RdIX0UW3k$EI{4F^ik6-2F zj*gC=*49?6f87SN>$(Bm&P{631d~YsBVG<;X_QobW zTT#>S;O<4i_&&A_R@;63MneHhWmXQfwY5W*Wk_Ul)A*SI486hFcWyvD8_gcbtbpDL zK!(X=I%0Cu^Wx?)WA^wu<_iH)mQYY_jz^Lum=xuZU3e~md}DGA#`#YVQ7+bm3IV_y zH-t-I#uGLZwA3op$~L+j?fCL74b^Bzsl12%{e6trCy^;-k%&hdO=JMMS*KRW>wJAB9qB909slU+@JIy5{V$0G~v?V zAZGjld|X{ccXt>1`};+b-|rW`x7Ur4kzs6XY(OCyGvRRPG6O9xE;`+Aw}a<-`jiWi zcW>eI`RLf%P%4#>&1Nw>JBv}@E!3)euvjcOau>W_?=y$PF??rgN_p})NEayrg&NDp znHQJDW2YEQPfsHl4Au_;0)c>C)3glB@_0PxaXRT(0qJxaYinzwc9+YA&dyE-$!%_K z%HeSM`{8Ax5^^+&7~Q@Lp->2RyB%h;Sxj(ucXxvPcClD|zOu5?LS?I|R4Pk~ZvFx_ WAFY|n`T1f10000zR>QH2KN`fNj zBHaWZEgiB#>49kYe(borqx+hj`JS_1d)R}7LjHa+tu+qg(TC+eO4&q(D;ZL8C8o8; zLEfZxiIlQ~iE1b1qBZ2=VhsA0V`*@y@M|Sc2@Wtadv3g0hOc*O(ADVFjPTWAYz(JXS z8MBaa%aCO{h8lvp*ONKIh5Bg|-DNo^;jg=q=uDZ@vodOJXfu;GK`ze`H-VrWK!nUg zje)ufRUJ&ouB2nYB2_pI=gji&GcuBL=+DM-wBZ)fbc7&a9AP1Ztk5)S4Ah03bqXOt zxx}VdK|CIVljyc=oqO1G{;Qew7T~%?tSw{^mi$E(2^Td6>M8+m4H!qrBtj~%w(Y~Q zVrXkVOEN#2&@(U(cX3H&S97B(;-}{)?<>?0)RjVZqrJ&ONChgCgE9%PC}CSBp!+d1 z`bkAqacXYz!94aLsJZ!K=3b*?T#ge1nL>bsZNf4&8mt(EkXYZ?MK0YwH2ZOI9{(VN z&%WPH*v6AY+yG?)mZ`CxE@5ZK2lW}4Pr-ctMRE2V`yf8$PurT4&^p3q*2kt>M8OM& zl@MbQ=U&8BS_$dSjo(q&2Pyd!8`}{~Xr#A_DDL|G({Ha$;Xe@?&|@q4QbvV}D#ixB ey}zEqA^Zgf(1+rQ>#k7%0000@ zcBf_(#ZX_-sEX?*?9!(0{Bl__G*A>pqqyNz-JwmMeLB3br>{{IMX~DC@qV7t3SKP# z`S8;fU;WT=%}r-cOzypXPb*-3Ew8%sb7mA5#*W8%v^9cO0QbA;S*^D+wQoBcTSq`E c0001h|Fw(1Q4#~PfdBvi07*qoM6N<$f=H>olK=n! literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/contrast_decrease.png b/base/resources.pk3dir/gfx/icon16/contrast_decrease.png new file mode 100644 index 0000000000000000000000000000000000000000..0155bf5c0bb0df2d20b1c9d67158f743cea1bfa4 GIT binary patch literal 695 zcmV;o0!aOdP)>d)<)F=Uup^koXw) zd$^lX+9>bw{3ek|{4)BRj2R&K#BR5r2Lb`7+wBI6#iH6JNrK^U2-RwJxmYY-CX>mM z4q^mMa=BcnTrSh)a!CmxbhTR1$z(#u<1wAhW>geKieQ?_WN17d4{Nv`MuK3@;c%S$ zd_FLn%`l(O0SN$!K$c}dAdE&Ms8lM@>-Au>*}RR#VjRQn{7EF`_xn9os}(Q<<^b#U zS`|$%7K@Nhr@`rTg3IM%y?Lb*pi`LVd9_yNtSE|3!1Pk7#QLM^tyT*-j$`SEbpkvD zS#&`Vbf6|IvIb_^G#U+HzNiQFF=~@Arp<&!E))vty=K>R4WkiMF#1zAHdclatdTuC z^#hR=Y$}1i*aB!m#n^+3!C(M3n@vxffsLg|B7xA|BRIPM0)&+sm_Eh+0b-4z3lhlP>ijqV=Y(3>@G1n{ePcPzh>Rb@txK@5f)j3gr^by;*J!Vt3YP?H2^}0d}_~oR8x}F zP+7a)=0c0KaN<-oIn`BFMIUPFOKX}*3K0^y-dJ%y9^n(i;V{Gv`#hA~_=y(=(v$Hh z9@bW#6=DnwYZb!al0($-+uA0}H@EbmB!oc|oqS^W7)FjP-#D&_;wB&h0t_FABhMDX zFoYpm3FmdXFnn@k+essMa1LRx!)Lnj$+Lw8J&aMR*kLPSjxg$cHF+5)JW-pEc15Bs1GuRuW6QjX9FP@ez51?&;seYxIvr*M3QBdYG d7%TMO+&^g%zBmG9R)GKj002ovPDHLkV1hr^w`c$W literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/contrast_increase.png b/base/resources.pk3dir/gfx/icon16/contrast_increase.png new file mode 100644 index 0000000000000000000000000000000000000000..a3e7f5200a762f96b74035926f0a45f22d8c2006 GIT binary patch literal 717 zcmV;;0y6!HP)3IxR-RFpwsgT-ZXG)rg2BNZV+Y(9X?3n+SqH+PP^q{w;SVX;^|4Fm#u!Y=(55^*>jt16WW zPyq$Nd_Lz*@YCruM59sA>2zQ)7^pV)MFI@+noK4>R|=lZW+DOknM{W2!~3OD3G{kB z$@hu`xNy-=MZp z8d9)8MgaSriy)UNVEAcBu$;68`}KMq)M~XTo50dk?02nTS+l^(c{6;s@txS0*5GlW zQ20tME0@b+&b(~=F5g>&3zl+3)vn5kFviW)4#^%j*FpW;Kp>lIrtnq;t75M>sh>plf=^)<~ z2)YS^r^O6n8#%l4J}>9+z5=m&1VRZVlyKsX)pVQF#;oDit@>KHT>wt9HSZFjPy~29 z&ughAz)8F@X2KXBpKk(2+_AqA0nJ!TjR^1=^1*;UeO|FC28CD%7#WZ_%TCJAaY&Mm8y)OMIz{xTv zv-NsS=ku8!kB7kNbfU##LA6?qRjXC`TY(o@zh19|h5c|ikgn@=xm-jHqLoTTFPF>m z7lD^;W{`Kg9c{N;S}s?#-|uO&*$`YABC4vgLZKj;0=!W)hfz>i`(r+i9|v(1^AeR0PN$?YPB*gBP$$Dr&9sLMLZsV3p5%H6&*(z zAR#L<0v3x!z~yq$WHJ$x84iaOi^bk0@cAnE`FuV_2CvskilUIm<1u%{Mxznk?{_Md zN)(Ai-c96lm5Rk8Ll3YFyAU0Z$AXBgNPurnW*pL&iN~IVtNi+^ULCu&uzdXc=%tD#Ux p3j_ihC#gQ4PvPIvUti*a1jn*n;#uCM}X>FjAph?v>HMSz1 zf;3HmQp)fUut1?Oj4&`TKsnC2z=)5XlYE)v=6sKH?ztlXFfxpDv!GF+Q=nI1=tJK> z)BIUKOgy7Nd;3kr=-fVHy#5%we{jeLLt%bvH^RPlC7E$Y*@!h*`a}?GjY$GGq&7@a%@Tx%C8vwF8lXfELN2$TzXkYy*Ch+<~�$xF_*&%15 zB*T_3AX-q$zz}$UIw`+p!e)WS?n33<^>s&1&I(xCtWah->dvT zlk;@30hM|iP6P?&m*26-MFB%#|A5C~VO%V{IK>h&5)otfwqcaoAZ=g@xqS*twq+i< zM8F>m5dn;kMH#-KMn+dml*sqcOVNV)g;%P8{>x676~rb~r8XfEXT=e5{>~?YOAmbz zKdzITiDd+!tv0mR{WeIgd~}QXa<5RRwMm-P ziA0tOonx6Yn5=ejf?oZ#NW-fNn9t`>tyXEJQW3uee2VqU%jL3O zDwV`9fKS`>DOS~Au-R-t(=;CI^%~IC6G8}~xm->#0IXj5xnaBAg4Jq;LZM)Y&1MTY zogdr{KK*_l(&@Bp09dmKlF=%PEEX#Z3*_^8ST2_gVCI0`ZpZt9?&9${F#xSrOT%X2 z1_WS647=S9i9`Y<$qWvMle=3i7I3{@Argsb27rx;18@VDf?}J^#xp0ANidltP!tFM zkJCUG;c)l`sMqTRJC0>w1{7mfbTpk#8NkE=XdU+r1_KC%La!3oeC6?Y43EcyXOJX` zizkx_4@FVn{axYZ-EKE17K;!F1YS*Ka}`uor6_t%0)+@2jYh^eQ9K+DQA}9~Uk*|> zn-w#ejE-YNCx^prAM7yza-4I45g$8m^55K?|L?r+odSTVNnJ96LXt|7TGI4L>d~Fz z&-h8>1xd<>>vgSt=Y;X^$Jv9(As-4y`R%SPp?5wYYBW2LD^|g`7v>f>k`%^{A!C3N&EeR0q1EmI9?j zT<^fuCti3LD9UEdoCoe2BcvKUvD7KhHa~-21gL%Aj#%s&OGVR_$6iSuSoaqp%eN%J z76DWmU8pyEP^yWrwDz7wF9N262N52Jg#ie_jHv7Leqfv#&`?`&#}Fpfom5)T>7B!> zWsOHK0qlpu1b_k9E1Iu8-65F`u4B0T$PKrdAs|z3NmX=VY5BDbP=DEtvNfR%4Y5Zu z5VMpOD@qkb3GkT!aIm-Gn* z`85iZ>7zVE#RF?u>-GjXzTT2IfyTsX6XN-%yiPPHr0n_^E8Hzpe7MH(L!#e?D90zS zP^g}fN@{04Qcb!flJ%iEo~?q;Y!zl{=dXt}`IHwd0cyqO;QYY^WD0dM6YM#f=E3C+ z!2-R=&FDY;{gfv^)4f+|?c7Tj^US!+(gqX%T+i_HIx{<~voklC*uOv1|9t14Z-oeY TX1>|Jb)Dfc3=%9wAxt9|F z+d&sV7i|Ri?b*J^NGvsH()NE*Nyw=rHOq z9m05cXZVv}DLkU1y6J^t9{Ie+&$xra;?lD0_4(zg1yOkVF~Tl8PyD8)GkMUbW%rR#bC7lH zW%k*fs%0@X=TU8A0Wzs(2GkeDrphJpj*`W_=V8Q>S%%hUVMG&|vdP5cv~+zSM(r5L zpk_q)&Qt7?cq5sCsciwPJ89hPlW@GQ1=qU$Sc|6_M~rNO8=m1wO9sa2uK|I2rl?eL zT~6cT0}tkd3eMer$IdfNqs&lA<*}XA&^z>6AT1e~Jc~;*4J*EzV+KU5Yj?Brt{(qr zZ8L5S1Q6NMSc+`^00WL8nY7Hn?e#GOich5aUJ=JG++neU8!4Q(I1!F%48;^V^!D|a z4UC`W{X$aBU{}jyHt+*yo5%4bq~LVpD~Qp(vO#Dw#r{liJqga{D7R4KaEAERXdHzC zu(GYOsh_;Up{YN>64bT|>t2 zQspYQIp!?(;ZbSE6T)gtVKbqg{VOuYU0$?tJyJvGo4;4N@-ba~vSMy|JkGaw^$FY~ utNgH&m+yDjgvO2${t_?#`!W5`bN&ejO$WoA0n6Y30000VN9{w9DwJzd%Gm5%l6k(Srw1f=C@i5k%a|<)Grew%RTzD&|xaqcXf< z9*@@$bXSuRnUR_GMnrG_gFk+>+ij)QYU#~plQkL*gL7`wYBg4^R`qhZto$k<$f_Xo z<#I{K-n-q7Ow**(=_LO_v`{FR`Fvje zCh%1@e~?F`5v|v2G7LjvFc=W3dWbN_cqWrko&v(J{s`D?He|Qk1!*YBtJR9ERvYzt zJ(|zwGN#k%P%@d+p8}#;49X}KB%94HV55G&Pm9Gu2v{Y$-LC8hs*A_t>?u&M*9|ml zyWL6wWCWZ}Ck=-~vRJGF7W(*b$n)iLp-3cRJO#v!q9QpfKQN-6~U9q_TF$F*h9sL-j zNpc$weSXQZ6Gag%5kOy9HfA1@g zVA*&|VjFHeVhIV!`DzQM7F-a@NRTNvNlYYp4z%6NAQuJno^MeOJ!7dzy8e(=;etr6 z4q2h83Vb36o=G4!6u79$u)6u4LoN!;_)kItHmh9g5CP1HxVh+sSiS*Mlqx_uVfwL~ z+}p|}Y*;r1{g* z9DE4_W&SW~qUN5hWN@-RUJ#q3Ngxr&iJp;+4aEd;HM{A>I)B?7>yL4`Nc6h^we^ve z3YC6fwXTqAQWr8=Cd?emR={YnNptkhuSFVP{Q?6Lt^ zqF4A?)Arx1JpP&Pyh<4sUhXnam)AJ@xmkE-VuVGbg_|=vm|INb-=FD!zVlDxJ_uiv SXLQ>D0000yhD literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/control_pause.png b/base/resources.pk3dir/gfx/icon16/control_pause.png new file mode 100644 index 0000000000000000000000000000000000000000..2d9ce9c4ec4b787b77e2407809c8887b6252dc6e GIT binary patch literal 598 zcmV-c0;&CpP)U3VE{tZoOXQ3gborPd)C!*bfsFfgUA%b`K z{k54{z0H}ACRrHvW^d-rdyicUV+{VYtX~gCqfs0|(-=vN2o1PiuPW{>+#Atov}dlj zm>FQRf_YAoB-!b7g57TC=llI0*6TIQX0twmlwz@1Su_y<#c()O27`fy#f%p1x~?-# z)7Wme<7b=AhIKj}t=(=bMjvNzr~MuZg=Ct#TCD`Id5F*FgY9+;-ENndyrfd8-V+sI zk|x?lbD>axN~J2Ai^W%{R^I>_0Z9u6gEF#73lqsO`axO|3~qzj{hRS`0}LC%>-AD? zlFkeU5t@ED93Che0EA(j5rE6(g7f(t5ddbb)O7oPG}&BpJRae6I)RyiO6J&XwmSe5 z5%qypxm=P~KCwUk1<-E^%&v%&sfQfOPbAd^dMUz$2)JWFR zn(5E_apM_H=DRN?Tj1j{9obJa2Z=)=&L)N3y%h6eCr3~F>o%;x+TQ>p^I2c0Y>yvi zIld-=tn@%V9S}8IT_{!R5Z+_Ch0UxTYjubYFr%4GeU;lC74TEKeW=Sl5HvMAeX=Gi zUD%DrWY78$Ld*n!b75@ktedM+7b-uxz>7nb#SWC}9Rsqt73OZQ@HmbM0hR#sjmFrz z`Qn2R+;S%k^W^LfTz4f%8vIhZ??Cw@GT3qQ2$+f;Bm~?nEIi6bESWz7m0cmx39em$$Y&@l88-}q`@)p_|Tj# z*1_TN$urdYuZuK(mFK)s`?7zHi^MWe;3cvrICC;Dz(yzzbJPMi?R@k1RUUs#H=pHg zvrjkZN3JD?ns*D2owV@K;bCSR0s0c1`uAh{pXdA&89xkjaU%7W00000NkvXXu0mjf DW6MO* literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/control_play.png b/base/resources.pk3dir/gfx/icon16/control_play.png new file mode 100644 index 0000000000000000000000000000000000000000..0846555d0ca84cb99d4c70dad80144a232604041 GIT binary patch literal 592 zcmV-W0k7R5;6} zlgp~&KoEw{L*wq6jM9+RMU)_iNO6K~b@$|K=nj zb2!5=4Mjq_zrU*f>U2#vSVnMZ9ja4cY`AdOM*t}k^goWqfa3Iq(>2kSH;P81hAqIyBm_{t1>+!KRdtb~{1AK7>C~ zD-Nov`UX!X6ET_La7f{B_|*cRuZGR%^C`gjd@jmW6h*+;8;{2{8ja|Fzf-YTq+l@k zGLg?!DijI~9$+CG0*bxx-)TO!p6i!Q&%N5)kR|pVJuNho7M&@5o@ZpsgYXg z6pCpqAEgW*0v6~{n89ISU>M4A&V?DNy7MOQX68Ka`MBqf0l?U(ZY+X9l}VLZ)#Om- z;Wxvd@uT21RmKNz1dH$Bj0zp6>Db9B7mX*l{i7uPYA;7kd3g)QVC)rxA$;8vC|jea zS%$3%AWB_OF8f4{mJFo|55c22v$T`7VytGO85j|cC%=pBjskcjxd*)11x{77(<9$R zNrwG!M09PX(8Nd#urDkdGiz{FkfHKZhPUAguyq;A^$wKyj&8EE8)WXSvDl6Q4NN}z z2Zd#i!U*1a7=Vq#3W3jRZ6Z9$+&MVBAqrVEFbBV-XzUqFMNrFnb9RsDb%-T!q1pza zrNBj9g5~vhG_q(g8Ht^6IILQuOJK}cdY)autaf$;u_Hxz{;liNSF+ zP7JVo4aPtM&mF+{jGz3=veK}ME-bIS)D6sEz9#6p*nx(m=)Gd##2kGE&YZW%&7_NU zaJbxh3nsTeLlsIj==Xtu`3s4ZJ3jM?zzC+xEl8DG(CzhM_b>rg=Lda=hWnnX#UBVW zoG_R&W`Q?ax-3JI?gr8ns1oY(%Y_9|I!G4+85=MXv^z2{WgQJlI?w zaoVx2#b| zLX6^UF84fh?wy$kBLC~BD2js0>zp+XR}r`}LU#$3n|fVSTQ&_fqK z-dP1W_0w_)Fx(96Hd?S$6Ag!Gb0{2;SA#|hQKxxo4lC@GkWvoF>433OT)ML_c*YrK zxk(GV+5xw=j}C#*d_)ZQm|^vSE$e_Rfi{EB*{sr@#u0%!GuA`kT6eip5)*9h(VoI2 z7I~jC*1{1PRmB(0C&t&XN#G6@eBuONxMW%!n+~_GQB^!(14SOFz%!m0KGcES_nU0K zx*VUU%kcb!9C_-b+%XxB2spb0jf9EGvCrBTt7=&<*|?4A1r-;+e)BJV19u#CG)&jc Qk^lez07*qoM6N<$f+7R3%K!iX literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/control_repeat_blue.png b/base/resources.pk3dir/gfx/icon16/control_repeat_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..406ec333bc036690d4639cbec70e8f586e977699 GIT binary patch literal 750 zcmV`dI4bfJkF0x@cXCL|Igq$5O2KprVjQ%O+X7O;#( z4BD1bI(<+cEez0UoerJ8pvUZH<2j7y zcZNUt)xrxJYFpmPCdcPpZrKy&*VZ>ApFbcitp@qg#TeIQPnn2A+}{k&#TSQNduHE8 zR1lLg6t#%bX_+CDEg*4_f_v33^v*=h#I2ZA3~EX24{j>CdV}A=`*V zT4vz!`I!OrPI2eFNk)w9XPLPE(JbD&MP{&ll+#ia(bqqy8yG)*4e)6tkBnME*Ypl9 z-y3DbfrSJUUwt@@D-R}c|4op+OgNr~#cI=AsIxgE+;$>~av4mxb*QrFQBlRSu^2P( z#4-pavM8REG5;k1bN7TkM8nPocv)tTbCDe=Sn=D!1EK%memuVc8qO zwkWfiP|txa2~#c~+AY08Q|E`jSGoE#-RjvgwZ5L>o_F>0mY3bqi%w2z>#*|89S-gW g7yS2U`k(Lo6ZXgk;$VJhmjD0&07*qoM6N<$g5UmA*#H0l literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/control_rewind.png b/base/resources.pk3dir/gfx/icon16/control_rewind.png new file mode 100644 index 0000000000000000000000000000000000000000..c0294477171e87351813135e50e05766b5607b0a GIT binary patch literal 614 zcmV-s0-61ZP)jUp9KZp49DjNvG4H?RHybjH%6LlQtR+QmfUZ9|2q} zb1_@3R&Y9<;C{c0I3ABMpUdND#U4V-<+4^P zmE;$|hi&#L-fp+BSS&zQRT1m;8m7~!4xyB?d_FJf0A4Ra+kcClPUnkQQ53O{tKaWK zCX*pLfH#XG8LeWiR_h-DK5r;AuD_5{@H zb&4IwGM39FxLj^tf(vG|nGhgMQJgRykHusLg8@XN(Ps&Kz61{+kB1PTO^?STGGd^0 zLI@0pL%7{;P%IW991cI5$mc2*3I&EG;6f2*N9brY5<+}p0(|FU#zT6!NV!~2&StY3 zjt&2KI2?o<1mR`E%xIkpwLl;se|weF>9m|oCK)eD*v6h<%{X^{d4LO<&*zhW{FoAn zgcONHNGKGd!C+AJ`~4~xQLooa_`CG$*Z8mT4&e|nrfoDRBme*a07*qoM6N<$f-U?5 AUH||9 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/control_rewind_blue.png b/base/resources.pk3dir/gfx/icon16/control_rewind_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..15d1584bdbb2c26a9fc4c8269aa54615a58a4657 GIT binary patch literal 745 zcmV1hlor z)=Ec^h7>5J3?Bj(D6|X+0|UcQj&m*_Qg!D|-c07sd7pF6opXl(U}#WhWg0W$d_xV%ATb~UcS*dC+@kfS*m{?64KBH-eM78JQAu#&2c z7TM!?0X98;&a@msh@1ehFDx4~_smCS0rm@Z$dv@5Y^ec>Jl}_`uDh5!i#cpZh5&_) z{y|~cgJzZ1d%`?CxkdJIg%by0u(~PqB0%Zdj?maMmYO=M!=;B#0>~5_5YO>&?w*4H z@LRbi!eNPrxg`gUUIeK8JG(3%R{o~|7so$K+8_qZe0Iz($pKd%d&oOhA&AGYXkKE` zO8~w=kN^smCS05H!-WT*2mpbXAJK6B{s*`+;U?8|s%XO8{Hs1d`DH6am$(L0coEX9 z)c+Ho)WS9-4?6~g4NrO@c2FaKCYmmR!DQ~YpfIn+s8pr^?KThtmU&}3Kr*7R^y^Rk z5Xsb_*=oc3w-9KI@B4=+yK6a8uQ@#oTkf1PnlL+NjAm=Zh)+xqld|idFEF=^(avw| z4U*w)Kx6;tnV0ZXQD@SHtHr7{`Y12 bpX>Y!%!CO%>C8GV00000NkvXXu0mjfJYGkQ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/control_start.png b/base/resources.pk3dir/gfx/icon16/control_start.png new file mode 100644 index 0000000000000000000000000000000000000000..7dd1c07fbade1ec8d985d95fd89385667bf83e3a GIT binary patch literal 604 zcmV-i0;BzjP)V=42{wMyJ==FL^x7*b^oepca+Xm;{Xf~Uy(P(J3T21*D zAjGN=^W}0$$K#Q1x0{T^;Xw2GoT}9-uT(1Pmw*qkc|M;B58k`oj!e^})9EDV04fefqL?N$IB5&$S;dHP}hDFLVh>akw0DUnDp3(#t{3=|9E&1OS( zyMvrg7bTNPIYt05old2T%jH7RXwM2F~VlEOTqhl>IpEJOe`0XNaO*i*Xs-w zM;fqav)QCzHk(OTpMddrEITt83@989KT;6=)$sFvzsthux=wFzy4(=~R{#u$L%LqC zR4f)L7z{p&DEg`t3I&ecu;80x$iEP)ITpohD^Ctgf=H~o==W*|y0)VM;-LQd9lR=YF)677| z!Jh8V_;KSkP5LJrlF9S+j0qkk+2iPm7~x{#{$ZSbvzK9J-4zqYVC)27V7~717pTZd znit9v$VwYJS3ROyLxp^?0)a!0U)oMn7(0Xv0eUoZ@gH)t)d5_J+J%bT22oSJ)g^nf zqQZVCEIYOm2+rB;rB+cID%~N1o%g50=A<=fWgC_GFUb) z%s4&22M=t~3G+RMgR^pz#KbcfK)ZtsdJ$j@d{400GnQJeAz+sPu#&f$`6hKh0J%~V zq(%oWs|qZyzh}{lfSK@dRK#JSxg@DDP3^*cD+kP0j(npKkSQvp3bk_uYtD5My##O+ z;RpcDs9R5c#9;NFP5{z^GN_^r%PX%(0OOZ~7+aNFP*XZk{E2|i#E`vI`YjCrsfz|V zndEsDXoqvug2CxaF}ZvhdOaY6!{9q~KO+jO!o5Vk0qt%NcD}`cvVR;6QTNzYGWq-= zUX+?7V0e7VLW2m6_>T!vT6W8eRsOC$*+0hNMWWwDsLfA)S*X-WV71;M{bCzP)O;^z5vZ zY!uIB*x&E}vNJj4{?GTJBigE^o7UKdzE#&EBXnfjM2N9qUNJ=7T*(!I*v$dVF@wV! zPcbfCO)dpCHwm6#49koVc}1IZ;f0opGWdxBx;Rl@XzG}46S&UgQ6wI6lQE987w+r= zQ{sp)?}bM^PSu zImdUlKjSCCE4u7+Z)8{a(f*WH^6Vt$sa4Pdn>Gm|hqxOd&DgzL7wR=Ny zr>K3{Pb3xpRu)a{!~pxkvN5v>H{?FlfAoQu4ArC_RK=cUva=WC?yvFKjtvbQVdguH zW&aC4ZFY(9WQu1%h2k`_XyA-}%`(_CmTH1G9&H+WxB<7lEP>07F324X&LtI=*Ebks z(O^1xbS&VonymqWF(ZPe(4cg#Lb0wAqrP?lYk_qESz>U=ricNSk8nlkTJZI`2;B0p zP~cS}qly76ue`DhoFBiW8A<6uOVzAiF)Myh40}1zPD8j{)c_{NT znF;osE(x$5WnrFL;%2<>{$AzD&vfr)$@TcfHvM#Qg`uALgat1xJn{IMSx=b0LuW4k dO#kzpe*)_`5%$M*g6RMN002ovPDHLkV1l_FIQ#$r literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/controller.png b/base/resources.pk3dir/gfx/icon16/controller.png new file mode 100644 index 0000000000000000000000000000000000000000..5cf76ed029a4468cfcd05c1a50089a98e718418f GIT binary patch literal 666 zcmV;L0%iS)P) zlg*1#VHC#iD%uAHty;DTg0}q?ty;8bDFzCDreJ80{BB+R< zJENR4PZMQi-K$n$6{M+e{`y zCzHvi{{^55g~BV5NOa+FIKC8%#WFEpk_S+;0uA4flMsu=wvk9g@eiQYYGoUZ#;;nf zwk?;-FdB`3VHmiWEa5y`gl|tCa~huHAQ%j?r0MVf0GiFFt=sK#C%yTk;Ec=V5(eW1 zy!^<*iw^+Bx5qH>dSE^ra{Kc6JlJfuBMv}5)@Yi~=Nw?K*=zV6|Ft zLOAX<8jU;B^k)=l4vT=l&3kn^9UxVL)9GYU)9I9}vfXZjQmOn(B@&4pQul^EU^1CN zHk*ZXIt^qGkTG9cEEbJkuV?WZo6QC!5(!Z8c%13?`&?OQ#B#^uF;uHnNTpKPc_2n0 zqyCI{R;g4puH&IXp%AEOGKB zFaZe_Htgq(0OW7HPl9o7Hk+@=e6O@xZTY%@-!Rz$1Rlkwh5!Hn07*qoM6N<$f($t; AN&o-= literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/controller_add.png b/base/resources.pk3dir/gfx/icon16/controller_add.png new file mode 100644 index 0000000000000000000000000000000000000000..efecb3871b9220d8192afe89ab66caa666b69e0c GIT binary patch literal 759 zcmV zliy2|Q5eVHtNwu?$ZopyMku8m$t8i5HDPWtH@CgpQd`@%^Bh_X>&gS)_izr+_j8{2InNPXE|-9%^dU|HGTJ2nWd;3w^ zTUb~y%+JqP{C_nhR^2%i$S;f+0UmhZ|^^}Tt(B1%XlkG&}cLe#>dC= z@pzo4MMg?Dl}cf8aS>jxmnx4=u@$-xP4KNs_!w7Uoqmj))&^W_y$E4+baa|3PeuZe z+2L@+IyySk=H_NFsdo*R%AQX)cs|=fL!5a4>&zpZYpE*DIXIqX#7#bQn$?i2D4u=to#ZW93VYAuFwSe zlV3sn^F#p zO;I0mE*EY(x3LD!mZT4XmATQHvj2Z=rMusL=fYxGPhR+5xQFxo{LVe+{J7E4QNzf{ z$bA6ZVZ;p&4_`2uOiOyb{^Fqk^wMgzQjJCvQK?idhXSb8>SIc!a#1dqFG(blQxscX zULFVrgS^k@<2@cv)#Y;e91h2|{{l#UzyGmVEZ#8~3||6)K!}-l*#lC}@59!t15;B| zRlD6T{|B(XzV2RKUEN<m<3!P3kAOP4$g-rQ;UI5gU z%jNJRnMZWHfI^{wa=9#s;FR0n-(O=*zss@a@B}z$t}7aif>jBl(a4js*{o3I#>NH| z3dL7$W@e^F)ViS#$Ye5byWNyAZV!VHH3C6A);3g&}7O3-NBmkK$ z7E4?vlNCiG5txe3+b1f!%nVZp&~p;dv?2BUI^NtmUf^stTQ8kNlOO>74qNY1_=!ip}mL@OCus&$l-zgamdQTiIf4 z4h|0PvH9-x_4S1g?) zliyELVI0P}>K|z9qN`S`S*>My(M=b%{)4tQH*2fA!Yxx+hAy!Jp#(A(!X`9JVhTFY zg-ej%v7wSpR%?VHEJWq^4>@2YPwzR6)~YMd_MEeG_CBBQ`##_AVX4(>nM$Q<1Hjsk zSW2a`NiLV$rBdmceF5m((9jTfaB$E+FfedvUjTtXaDdO}FYtIgJBPzLNPqMBd?Js> zQ+GHVb&JJPHJi;2lgV`9zW`cJr?aEGyL(F}lZ9L^mzS6+a)DOP>A?Do36qnPRjpRb z`v(vR1m;&(R(>okEmgfvU5Kufd~Boc{;0g#t6ZOZ5K44|Q0E{Ba| z9?^|$L_J-|gbYXoGz^?xD-;U%Na$BsB%C@8_}ko2WLb^W7cFW#YY0qV#dh=qv&&#G zh~D1bHI~t6+@q-tLj#b>WMF?cfzQS^R8wzJO~{Z9n_(SoM|r1&N~HoWmkX9&uP-GM z31(Zgu}~-=olawM(Ffmj7t+BgRKGofTilB8nJIjHc^OuNlsQUgXD3)Xoz6-pPaA0f zZ5|mJi9Z+Irq*qJ*iF6$wRRJ3(K%FNJ;+Dq;26HN!@1j$WwY7OSmWd4_h)BkL3e@% z&}5ZTQ6iQ6ITBnY%0>BW+b@N#lcNkH=90tvw56Zv!r0i@5z^O^-|t5}9!I%chW^E! zddw}u?v|3NUJkXBBeXD2D#8Y}IRp3OGuy6*r%y4%pin4A$(Vu+6Ub1(J$$iFrNh|G z+E7iB43dUFG>uy66XHHC?0qK;41oNNhsj`s#bR-d^ta}Ea=!Ln)J%DVXDL#NB9$m7 t|0Lyj&_odvW#b*EY(2-Qg?mRmKLN4t3DC`EWF7zj002ovPDHLkV1gAoYv2F? literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/creditcards.png b/base/resources.pk3dir/gfx/icon16/creditcards.png new file mode 100644 index 0000000000000000000000000000000000000000..4eae583e15294a046d9ba4421f6b832361b7c516 GIT binary patch literal 693 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 P>IDi33Y8yO5S#uVwz2H; literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/css.png b/base/resources.pk3dir/gfx/icon16/css.png new file mode 100644 index 0000000000000000000000000000000000000000..23f3101811f2e402b8c581ba2e39977a675e0295 GIT binary patch literal 524 zcmV+n0`vWeP)`ZKMgf6%T?Ed*Cat6T(z(gze_Vj!CM zy6@eO?#%UBLOT}?40F9R=iD>%#+We%%UB#s+R_AGvw8Yw4_Zs>2F6fS)&oeXpp>-P z(4Hm2FoZ|N+3e;VNHZ};&)gBvnMk6jHRTlU@9U0$Oo&egxTGs^ATns~z)sFnC~aG*pjzb8G=xt@DLRNB;YZL<4tG!V^NUq+~Mv ztN7=;N57-Juq!r;ZvU(T-}ZaSebaUsBWyIhc|_vmN(Q*NXt96)H+}<~rj3txZX_4TvTUMq|>LbhG>RIrFwD2p$R<_?X9=nQy+C-KR+@(T#b~rFBi9 zr&5dmoxyQzf`pXp1)&Yw77)Uws6}TRmSsWbtx3IRhjPdcS z@OpJ@ZmytO{i^P5+l0rqtpjE*E)+5p*rVbL*xpW|(WoF2xulZw`6M+7fop`YNC6S> zQg}|jV5`?l*xE{=)v97_>t}iDL2v`r=>RQ5JN_iu51ZVtjDaPH(RlDP!p6H`bm zy@1CwO|?;sDQf-$1 zE-6j&QvG?{oz?v&g7sn=ABwA(pM8dfH@9GTeeh};w8Ol{_?_^>!N{=(Q_*RR^vCdd zCyVsQReUSd9%+Yt&P1|6?lvJv*d;v4JTA`v1@HWV%by88XaE2J07*qoM6N<$f>mTU AbpQYW literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/css_delete.png b/base/resources.pk3dir/gfx/icon16/css_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..326aba44079378741a091b4f6dd003ba16ebc546 GIT binary patch literal 654 zcmV;90&)F`P)38XA*m5;4_2X81rH+VK@dEO0Z*QU9z7KV=|Q{-f(ZT#9+ZM8 zC7_fnsFxNCDJi6tYD|LS+9YPPyE8k^n`u)84~0B<%#ZiJZ@%|tCMJZyAQs1fHZXzd zIM4oDLliOT0z%Npr3YY)gL5XMp`0^>VF;6w$Hq?efz%Trq8--+G$)eXF^VY0v9?y! z1Z2M7RsbE;2^z$AK)bFLC6l&P;AsNQ93hoTBbz;gZr4S#SwSv$PVR?TU0uM`)O8q! ziS_ljaNRAn&zO%mV_~0}z?+-zWuPa)XR)#2pwsz*eExz;u2hQhkP#4u^H3^~1k@C& zlQzg&tvaez2cG9*a`G}PYXtRr8Mb{G6BAdky^km%vj#Op-zJIS*7*W@ZXXS`c)k+))+Vdhr;C8eeeY z<}4EVlkh$*qFgE>ZAb-Fn^q8DdHMN2o$mX~C%AZf4$0~}VCex;!)YALjiXWe2-Ej{ z)zL)4`s>>E?w!`2`wPhyuT^L1bqV3iQK*+kB&6HxYc zuV5|A!uJ~JN`iLFK+hUNY(KxTRLIN^+19=6C^OCYSG2z~d~O;%?1}ra{eEYskemDc o^V=PR$HuuKY7+JI>LPpi2eb^A3F^mTJ^%m!07*qoM6N<$f>8%1?f?J) literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/css_go.png b/base/resources.pk3dir/gfx/icon16/css_go.png new file mode 100644 index 0000000000000000000000000000000000000000..6cdf38c36670ec170cf88493142a6277f3a16d3d GIT binary patch literal 655 zcmV;A0&x9_P)s4B8sX20TCgDKpLQ_sjDn>cie5y6M(y6rsZg6xGOU=ZxaAO6m8+|dxuFu zBGNt4z9$`3SJx3jF##lGBa=BsHrvDQ?mBC0v*dDTF$+vjzoN7ADwUOK=H}k9zP^lE zKqR6#%k{Cim}h(YH!Up}xcBlJcc1rjq`D4~fNCIwhzeD~T~G}G zY;G1uG7{wKut|Og~B%?4Kz2jGctagNQ#&#A|=vhMO1|Z1gZg5<^JoNxCLSt zViB5-pQgR>99yLw9)5kq(3xRWBhn#6mqE;2kh#P#Yv(jw7b2QgDqFUs#xk{EU4$Di*66T|{R1Dnwn-PwM&!!A#k@}#3E z!Yoi#RrAlc86_zpDx5r;LrhUO3LDGR*EaHLCC`_Y&kWXdlNuYlxAiMjEgv2kg2)MtT% p16oH?J8G4gqG{`|QD556{{`7)p*DCclOO;9002ovPDHLkV1n4+5xf8Z literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/css_valid.png b/base/resources.pk3dir/gfx/icon16/css_valid.png new file mode 100644 index 0000000000000000000000000000000000000000..4c72ca5a409ea885dffbb3264e2366fbfcc5c910 GIT binary patch literal 661 zcmV;G0&4wR5;6> zlg~?3Q546&Z+ztBFqN8GzR{3Ep)nU)K?E*r;i@30aMiL+tNwxd7upK8ZV?mxSQH`5 z%Ar*T#@I+IrS-H4hWWva@BVt7d)~}2tqd<*&Y649=bZ03bDtB2A&#=hAu(mbu$SSx&5U`}~?nFnhY5J!9yY(*U$u({C36O#Y_4|(d vR?5yHAZy=);3Sb;#Xw~LUCvQI=hpfQ1cAs#UOhiO00000NkvXXu0mjfn^rF8 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/cup.png b/base/resources.pk3dir/gfx/icon16/cup.png new file mode 100644 index 0000000000000000000000000000000000000000..b7bfcd15fb2f7ce658185bd7ef4729815e2f18b9 GIT binary patch literal 633 zcmV-<0*3vGP)DAD_Iw@kR+3LLZX?3 zyhGkEvUzKYKpu0v_u>?yY~y}#nAbh$p6}dm6adQqK)FzXa=E-qP)ntfS|}9Md_I4Y z%jHh8*{qt$WYlyzt)^0`-M<7XmC7CwTlIP!6`0meW$j(o%*9*fiupyDJZx7&n@&K>z*>QCDhTzTp zTlnzwp?s_A3C!nn*-|JJ`k^?T&hB6^z;e07X0ws&YPAxuvwwlMjasdSU@%xy91e#I zzZYAh^udB=a16G~?^>-EC_Ew4q~Q1a4;7oucH0!-LK+*Y)he3JCK`a7P}Mc?vlj7AM;VkzMEhOwnj`hl1MBj6s4Nlz_+^kH@of;eX>V_G&2` Tt35or00000NkvXXu0mjf&s-qj literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/cup_add.png b/base/resources.pk3dir/gfx/icon16/cup_add.png new file mode 100644 index 0000000000000000000000000000000000000000..4ecaece296e6c59fc3c208778e6d7eb5ea11c6af GIT binary patch literal 715 zcmV;+0yO=JP)n#+EeykZ4|N(vXz=Khh*^5}QRJzvJ8?K~WJw2M(8+H|N}Q?|s7nuzvyjuL8kf zu#H0s1Ok%Z@0Zrr)@FS^->lc`l~z|*C6C7=x!vxzUj)|I*E={d9*IP-xw(n0tu29k zJ}+V}mlMcjGT@?cxmeIJuLP8-+pvxpV>_=cizp9L8M#J-q9?DWDtZh2hl* zJ}pl3J4s}-SvVYyhTU%OB-=8PtJSKws5yP;kI)VFqEspg5v$cIGj3;ld3hO)Mgui2 zqJKUB?VSr4Ki`RwGlvBxx{l(_-5&8RBs)3lIE*fYcw3Pn55AlK`4VV4N$bQ-BtN`QoV22Wtl z%SY>fDx3~2U4~}qDhZSsUpq-;W@g4uR%KZh^%7b_Cm$ZfqVFYsT)NL=B+&dF8Qa0J z%V;!C^Vv42ZW>kVFI3&yhe!I0Q0uz|S^d8IyMvz}hs|c&Yq3~re8%8{)F|A4b`58T x_T#bslE_Sv_M!)W`|9}RevWOj-HiQo{tZX32x6?^3R(aF002ovPDHLkV1l2WJjnn6 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/cup_delete.png b/base/resources.pk3dir/gfx/icon16/cup_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..59a6d9c614cc3ffbde67dbefb8b228663a9fc8d1 GIT binary patch literal 731 zcmV<10wn#3P)2lh<3J$3PPi4XeC4&38aV$Tv&_9v^Ek!r4eZZ6+yO`AwsM% zsZeodoR`{6`a8@6m3cp6-ZN!2F^~W2o?8Qf5kXz}xcv7&-*>)q&bU0v1sd_Jw$>z(j;JQHrWTkCSUv@0ts+U4ct)=dKI>+5Zt7zqZ0$Y!(1<#Gb~ zd|vFCOhzD;N`Z^Q>2yXM4o901;A9mi%Y{M#nM4%tUys2wI*eDh`|#rWMS;n|ewdz) zVCn5RkBK3jPGfO#QC?VBP?2qk$dyV(1l~Ko?~j-q>c_^$h7hsa?God5J{b%K$g+$o z7nyl92;Jq=c+jQ7$cY024^OG_toMxg=a(EP7K@@JtJV6E>2$hyGMPlFR6?~{6??f{ z79eN811}qaKmZntCBQTq%@}?zvc|g)60A3lKz8XY5{ZB}PmuYfFgG_h%-Y-AkJSYz zkdF<1zaQan7@<%IG#Sdc^mqW4uHBebDPio~3FED9m`tW^tf{H#U_CpLi4=>)5RFDf zM*4P*-hiw35K3?ELiSDJ%kxWc_Uy%ss__C-DwX?r2B}u73A;o{Boc_n;{qgPJh=;B zIT`mmfWGa(%@$;a4rBVLBFOmKLLz#--bYp?NfPxE>Oy2&UV4dNS7BfWW{)(=KdvKV z4IEp|X7f0otxR>(sOqEWk6h_ N002ovPDHLkV1fdAP!RwC literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/cup_edit.png b/base/resources.pk3dir/gfx/icon16/cup_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..0b8f1e1ef51432c8171204b03b17ba5deda6c523 GIT binary patch literal 778 zcmV+l1NHogP);pE=-K9H0nZ#HcDiJQAvy_EQm%EUkhUqm|YI1TC1PYtY7P4Bc*%Uy`Dq@!7@i-!5Bk1qc!B}5|wn{Z#m7k|-uPTM{ zsRp0Bn#r9orlzLQ+uJK!EEbg#dr&balSz8pgFXY>Os*y={1W5Ox z0Dm@4>_E(Q4e9xA%zrtHsP!B?YzdqVr(k~b;u({Zlasp)P?|%=22m6d3B(@n+pakDXPGE*48Lm5kuc8wk zj|Zgj7b$?$Y6a5L(jpKLKEAvKcUKu4Z)-5xSAe-dA)@wD3_s3CBqY!t5wr1^Katcb zqBSOysaaR00%n8oJ~{%fY(09&t3B1Z@bz;_Y?+vKD=yRZlUtGtmU~#})1a?n51LMI z0@top%qhKIzu~XjSg?DYbhCJK(olIIsjuE^>QHapxY9QM0L{1vkTsmPBLDyZ07*qo IM6N<$f(Ry4Qvd(} literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/cup_error.png b/base/resources.pk3dir/gfx/icon16/cup_error.png new file mode 100644 index 0000000000000000000000000000000000000000..68798748d2f0bd564505dc5e4b1b106bdfc6bb1d GIT binary patch literal 790 zcmV+x1L^#UP)&h=z!kfV#M-iHk8^b#X9p5(kYFB#urxC~>Px z8B8#0>Oc*OKnXOofdYvT+uFa^ANu#M_dbNEF)p0s=Dc&>{m%WqlXD1T4Er&PeVX?7 zAQFl6aCc9zQWOQ;Tf{d%@~>Fr$6PK~Xct37G8&DZ<9=MH({)&_RuDpVesaHCOqlS= zWD><dGO9=x^LY@}9{u|E3=a(olH_!esAk_yxrBv@>1u-Xryux#8hqOSxPI?*Rt9 zcc9T|)FOpK0j$1_TzC|g)_yb-zH&dcEj4{LVn`|Ru%&)xLU0W78BIx^F80yCkhB^`Fvh|T~4kbzdi{|b0g|G zKWxq$po#a;X{pMBGZ>)@3kx{`79f!{nM}~@^`MlXx;2TG?km9dS4_Wr1#@EwB)x>% zk9ol^iN$&;<<~|{5Vj_jH-9J zmXOowyyf@%!@M8JWHO+Hp%C?oEij05Ov_kfqT#M+~KmEP$HAVzJDb&E`~YK*bU&4lOS)!|(Zs4{tl6X_Mkj-CcB76>)m& zOQC6(VYI)Co^iwH^TA{?g^Wg{gvAz_cw=LOA8fpQ;*az;lwx&tm7D1GdXdmLU({+f zLZJ|X)MTKw9*UA|G-pa6%Sh(5WSv9DogDtoDVnjevcgLm9v=Qo6bi+>*XzaF+8Tnv zAm7*5*EuX%nA;txxY?cvU%(4mHe4TjqX!pSk!;NFGxCJkgQPp=1 zS6dIm?y!MQ3PVFfQj(UIc0O#t4$`r~>2#u4c?Ly7G799!k^3wG_f%KVX_2Ai^(CZB zV=$;0fJUR)PNJiuPldnE#Iv)raJ$_o6q3+mZASO#6E1vdkwQ9H0=cmP1Ct*4Y5BmqvZfD%J$-H<8Gup+=;CA(`eRKB3DR9Yz6rgQ$~*d_A(g^hJ7O= zBSAW2P(#)zPGW5ovgH!QmXmoZKJ?eOkw*TyzkCaJm65ogpML``p5oUq-p_^r0000< KMNUMnLSTZ4&}I$* literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/cup_key.png b/base/resources.pk3dir/gfx/icon16/cup_key.png new file mode 100644 index 0000000000000000000000000000000000000000..7ae160ce25e67b62abe27c2761781d424d3df560 GIT binary patch literal 776 zcmV+j1NZ!iP)cSajUKNoTl`+$cilDl%$Sc#xP(ezRoDoTF8j7W^ zvab!B&TV?yS8iixZf-l+o8N!i$@pA(RErP(krXL;H^5)edpm<)!~~-DYi5{J-tRLmC8^g5;7(YWOjZ7bcVSaD|L1RB+S{X8{ z3ar|jkuWsDJ5Y^J@`iVmR4T2^8wh=owZY@@!0-3N=kr0>jOX<=Y$b=VxzvQs$YZS9 zn!vHmVB}?MRAFJ^;r#7_SP%t+L9i@~Kp-G~FMPO%@7{KB{;No{4d8sW;M~{N2*TkoLZJ{?`y>Jrmk`p_W1W$KTR4fdw+0(7B5v8Ad49I|97STc zU@|&7>Lf<6SS;cUg7hGKBQ>PdK5TfZz%j>R>XE|QaSXOL>DCKban-Lsk;E>-9<5e8 zLUzjweTUv(Aw56C`d0}!XC=(NM=>V9%WK|_zxpgI+PmXp((Cm_I-M@-QPpEBdLJ9i z3D7-dP(5kQsnzPDzkZFgod;SS{S{HV^N4@o^1d@W<^2FSLkhmR{)z1X0000v^zY@WzjBN@nJgmb;$k^0I zBn6_*4Q1A*OqYr?whE?mZfP)@+de(dQy!$~QeXJ+KJVxIJfG*+`zipGe}VE}1$K6J z$_V!D?QMG`60vV>ZOv|OZqA0oVf)6$hJAf~-5v}E%YGBs-Q6vxz}Wu&K8}u#kV>Tl z$H&L=OeT|pgM$N*DAv~2Vu3)QTm&dsO~J)v{OT%NhpF9wFM)X*C zZo&K4F7o+=!^1zuzBHsGO7e`FRwJ zMdV53?XwX$9^S*#Ml~$D+X8FTUA%a7U+(ro0c0{6X=!3Hqv?YM&j-iga+!<8VxZwkFl`Epi;HHZqM|}` zF2IhoCQMCDVQg#+Hk%CwgMl;g%&nNG-wY8&4NlD2q>M2wx6yWiA(B0jQU^t9{fdSOj)uE-O1>@u6 z!n4g>Pfw4Cbar-T6gpQ}WM*b2(%;{Yp`jrWh{xm5Xf)sraa-Jm+wDembv5SZ=DaL0 zI5?R7`8g`eCBoINuC8Evd%Fnq_V%Kxs!9Ut>+1zi>87`L#)6>(iTCM2l=zw0Y7n?b!)0v{Vq^X?`7X(U6OE1$_Zq(G&d~9xR{?^vk qmL+^|XlQ66sL4KIj_=rqeSZLw72dYRtc%V70000I0T{~(qIu$a8Oa`;1VJZ+NJ#? z)Z`G6Xm=;i@Oy^O@W4+X<|%s@Z9U8K%Cou=JW=N{umR|dc<1KC5j-&Bmny}u z1Gr;ImmX!ZVOvnb2Z3IG9yvhp5kdn#W^JX2LP{w9t>Mgm0h`0-w1g7ei1zafe zdny~;a&&9~i}?5QG&nFlE(hRq9e(XsJj>7i0YpGB?|)P=F8}}l07*qoM6N<$f=`l= A>i_@% literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/cut.png b/base/resources.pk3dir/gfx/icon16/cut.png new file mode 100644 index 0000000000000000000000000000000000000000..f215d6f6b7c81ab344a3e53e0e5e756c58c82d90 GIT binary patch literal 648 zcmV;30(bq1P)Sxb0Y6MkDSd{nPwTp^L>b`TxVmKBiF^NLQ>My+_!0?|)hBPe_#}P$?rlUF;M20U z`oNWE|K(DrsR+gN%g)?+`OfqmmmiA8O_U(YfPnV(E$8mN{jZQVJ-L7LxzmTQJ^!PS zHqDyoKn&^H)Oq>Q$Nzns&wsn~^6P)|vPC&W#R9Kw95|FC`?q!91!~-K_R;^uDLWSs zj7A}sG%2IZxvQP(HeS-nn71T-`ku2F9(?#8KXKbp!Qe&~yaot4r%3=c-cDF`=YPn& z3!hUrzxqFO*Ny)VU;p?Y-nniMuVuI+UIUD>=B$ZZdhM^2Z-JeJcbDl-H)3?9>AG_?ve_7A86r2Wlb?y7)ShoTkzeah}rl)Oq{=a0=sekDkpZ?d4n{v>% zcgJPxg7sgx4Lmup8sO5j^?B5iYcCv|)*VgT_U6A?-trsfIcr`APCfD&B(EM;R_0K# z{lAb!kTg~UrQ ilDgypkCC?sx*7nVRiSN*cNM8!e}HvIH<9>qC z*u%>#zg$gv<}MShGjnAGJ2PkOK6By0hyU>tw;vUW?dQg807&yrQ=RMQ-E97!vNQg4 z-N*j_tUWjWKLolUYSQlg5=m36r4lDH;xu5ThU}a(Zr1-N2ys|V5M&R&;$i)N&feSq zmz{a{|DKP-|BKF6|7S?@XW}&Au#M51wR+0yLF^T(QZp|FIQ=hOeEQ!tf5-oe6~*Qr zu++b@&qD8hH!l+xRs;50>EAnPZ~Anzf$E{VUiSajXvrViWT0~Tn2ph=HZBI{xzd8= zCmhZH_X%+*U^QU6B!BX8TcaQ6fr?gZ%5MN_lGviFy#9=X>EBjP28k8wGE;1k*-!zk~CMF9Bv_3(^PCOq;$< zN?sD2BV4j9Yl`*+fsWQD?H_4>L?~r48B=l;Spkuc)A?yA6iP)R5d;DO`2BwH_g=3D z!!XcjG|+Ch%jCP5&1Rc|$N`LEvA9yN*EyX%X^loByIQT_h>#+l_9wi@{(Z?D2RE zUDq)j4#hY2{Z&BrR!Yn$4g z^!3C0RHpz#W@n--_jThHPEAe2R834DnuV#1kUlxXv}=C^n7~&>f1RO6h@8fUuT`wRE91*{Z%LW-oO8KckjTdf s77ewwyuEar+*b)ffn+a07*qoM6N<$f>LlT?EnA( literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/database_connect.png b/base/resources.pk3dir/gfx/icon16/database_connect.png new file mode 100644 index 0000000000000000000000000000000000000000..3a111977cd9dcd631ce1de85d5ce82b9ed477c27 GIT binary patch literal 763 zcmV-F$IpKw}ImgOJ; z7f9UkeLqXqGzqfxt7QF3)<-1d`T2Q|JMMspFO%GpXf%2y9*-j&4kHu_f!^zMI#5*= zjYb2lR%?Ug7ES=x*VkWXGMU+li3xBVcdBjIby2NWQLEKf0>=*tFc*u({#ko6nFJ|g z?nDoqo*3BN+=QlS$mjD227?eqk(Hq9I@;|vn$0FssT2kLZQ|-id%$+QRo569<9qv% zBnjnm8M$1JiK%TxQD9jX1VLcAK49g|FTrt~4?&Sj3z0ZJ?)<=HM1kjdtcg@W0W=PK zM#c1;^}sOgal>-cAqn6)AN*Jv@9IG$QdhCIwua^9WsnCLfUZ<{=zsybx}CIan}V?0 z(jf9aq{ui*&$pQ6>FH?{i$&Pv&LM~b`VLgXi0VYFk?86scD^Y%BLayFDZKrnV|#lW zi9~`4jsobO0XnL2(RM88rUON{plT*+du<%376#5=!^`(R3b$_eU!?$QpE}}O=L(Xl zTXHla@d^=2JO_a%GalgJ`5qcOEzISoaA`8ae&guqD6-iso5p&*t_ugM(H#y2M2}E4 z!@_QpjO%X=M%RSdwJ?@atIWY8Xx%dePiIz*;vQsHA#%EP6lrG0Mp{)++EaGtq_b;C96!L6rv t?W2=fDwT$aV2XrKn)Z2danU+@{s+9Sw^uGDfpq`?002ovPDHLkV1o6HVQ&Bc literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/database_delete.png b/base/resources.pk3dir/gfx/icon16/database_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..cce652e845cde732ac3ce9a4132b597301ad660e GIT binary patch literal 659 zcmV;E0&M+>P)ps_J1 zHhTmGl@tMUh=_=a3Fb%)BqZVTW3s!xH?UsxE?7A5@n+t<@6Gq#%m~l(@IOPFT;%il z03|#}Sa4nU2-$-Kn!4}FekQv@$S0FY$L9!N0g;c={9!m8K4zLG48uSu6aw$J+ii5a zT~sO+G#ZW9!I0fqFSvY9*@h|sR=YqL#x%oU@(yD@pz0* zr-R{eDEHX6V*RaK<|4rWl@GKt@8COeKZT>%ICBq4+h_I-+?Y*V28oxmqBc+Oz5 zc>4@kzJgDe<1lkKXYEtktsNC`FoTI)4qLaF!_1E&4qv>EKx`iUcee83)!MzalltZ# z3K)~8`*H_w9^uf5^9X)<39-6>(AOuJvu0IKc#FRkFoCa%ULtC>8v6bIR-H|{S~CWm zy|LB2yL+L!Vs5g8ONBz=aUzj0EX$JbfSV}a#vT*B_2)32Uc<0oLyzLS9V$=7hM4?~ znM@`|iEa~8)bZW?7q}d~l*7K(I`+@}grT|_=WaH**u tj~DMRZZpzVy^OjT85Vq(G=8XD@S91FH}kp`d7hyPh1 z5CCa%X>*RH50W(1GMNlqE*ChCgTvu4bCM)M5Co)BDTG2HvvyYjmSvI4<)A2v`CcxU zQ79BpEEdf*P56K_c;lUWy=bic9s#4IZm`yWps?HR<^;5uf_%3rLf1Uy7}ym7{u3SG zgQxL#;V@<+y-&7GK#MIB!!Xb^&5SuEhPoOV9{wDJpWonQN~qlHho`!h-y&cUDCjiw zot3{JSR;b3Z$U9V2&bDtVsaL$Qu?FFtIb;kXm<)qqyl<=9Kq@&_)r^^)N|OJWjH)_ za7i;6X_aj`duRB^h5&`toyKA^3V-E1_yb`=eg>PPj8Y+p^vFkpk)_tg?(s>=HO~R< zNVkfdL~{$}rBQI|9QHR{MrpYhcBg@2p$?h%pAnUsbBDUeKUv#oTc6-&EEZdf$Kwze zM&QwZLDd6D&pd?=1#1F{N2f6?Hf8gwvt`>|pf)ft5F|nm_AI~XywcT&?}K--v^WN? z_7vo-s3)9F{TXfF{hpqll^q2vdwBb}datvKg-yfc+gC^|#8-K5)%lB$rlxi}-rEGO xUZ|2A>wRp~(I5;*aZFyx-fDe3J-^%i_y?+(!m^mX(n$aS002ovPDHLkV1gwlT*CkW literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/database_error.png b/base/resources.pk3dir/gfx/icon16/database_error.png new file mode 100644 index 0000000000000000000000000000000000000000..578221aaab1c7f6f1f5f9eb4adf02aaad93bf407 GIT binary patch literal 682 zcmV;b0#*HqP)87 z5D7ClS`>i>siY*D_Hz7r-uLe7+&8^)8l^=KKF+=8o%5aVo_ns%Fbw?9=NR3j(`lIq z&l4_j&X15iM4%;qPxcepJA`yB7SpX9o27t~=V*Q3@ApT8!5};y58Q4y#D7Im(CKtg zsZ`KtG+vYMVmuzNnu#JnAeBlzFPF=roH6NRj2XFH&PXPcD^{M}l0uuKfk5D&XAXrz zpdx3t^?;lvW4&I7%jJSB%WyiKrmxrQq19@kTCE}+4x6zP2^(duC2SE#)bB9=iVf68`kSQeakO%!CNk8ZR-m z?*w*FFTmM-3w@)sMZq=#Gl@t{bZZ!XeF5)YAM_uOFn#O_`sF9!I-5*jRo65I^~*E( zBNu?dI#%!A!!BPRgIX3|y(Et%5U{H2%16kyA-q#PaP>1aiIe;_%$~lEAY1pW-a6^s zLLj7ztD;GSyh8%7JcV!OIC$?J<@T`{kAM$r)ZhXRM9)c@I=uF`f~8C*(=8T@aDLBH z?I;- zi%TAvMLVRO5!65AQFy%kz&7qVzqz^CG<5E!W7`eUT(0v?OSAIJVzcSlpH|(e&rbmL QkpKVy07*qoM6N<$f|gM=-T(jq literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/database_gear.png b/base/resources.pk3dir/gfx/icon16/database_gear.png new file mode 100644 index 0000000000000000000000000000000000000000..7c0ab2b4c643f33162c0ebd80c4b0f8418acef2c GIT binary patch literal 468 zcmV;_0W1EAP)xrrOlR+AYYd7dzkRXrG^eM& z0Ukd7oRTC-k|gQnMef{;h-hbg699m%$}xbdi0=mUTP2n)`eug$pemyB(~7A5(p8B9 zpo-`-pi=3n1vBanKvhJor`FPV@4HbW;>w}!^`!?_&$o+c)M|~!f&*g2sIl2&+nRI7 z2dg4_dK!Hio3Z4v0sAzDZropP7e%esh`Tl#_R2+_g}2LFOq{)tc4JXTKlp1=*9P-? z()(@ByuPV7UnkqEhjpwo;fJpEp5FC1>gt?lJU4c>+hFP*|&0tGt{!YG|5fRw@-UpUxK})gOY{KjH!sGG4?RHzSe!mY<6j86&kw_%0+>rt+UvTG zPNxG!QLHl_`>TN6lhf(69Pnfg>e~`ot!6OL_K}%<0mC@>2*2;ZcEFQ4iGwF{@R*{j z7!M|qd3hZgQye2(un7;}EWl(MRHj3v{mH--l93DO%KKRTaX^3MX`58z^<+{ z6<23&!!Q{PW`ItyBW>gC_$Bnz0p8cvrP&8U;E(_Zug)QpWlpZPzmjE&ksHm>&{4WL zcWMqjtuMUYDzy&;xOM)i=ubqW(I5dCx}hU{e1gb^CAKTo5EzT#!}bO?zL#36j`?8+ z3*~b8c`}*w$6_%IbOkHrWx4~^auW|u<6?Xs@2VxNZ5G?Ij>|hs<|oJSYs}?xlO%MH zkQM~t1b+*>9q#P0c*i_HG3Qv{e6_1E^9qr_9C}QDj%+r2jL4@6j4t)_BWY1InA104 gM*QcJxn<}50%n)c1HutrKL7v#07*qoM6N<$f)5Qpt^fc4 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/database_key.png b/base/resources.pk3dir/gfx/icon16/database_key.png new file mode 100644 index 0000000000000000000000000000000000000000..333414767983f2db7c3d182cd6b4966cd136a255 GIT binary patch literal 764 zcmV8(Zs~5pkxC`Czx(!Sg&Qcw=J& zxm*s3L;~q_`XljO2nK`6ZG=!LG!>7>X*g{!E0s!GG#b@LMn(oHxKb?nwAIwq;D1(M zUk?)G%uc_FICawM>MCqD8?06<%x1Ih6Gai3Oa{qh5=~7_6o5SeCX)%-Y!;H

    )MG+r&du`yP}}ZLJvbw^x(mR;6BNh>hu@++lBNk%}Ml69boS(bA<2$cB@7|GY&ZL_nTv=X48^gKW54ulJrmgw)_&D2zm?%kajBixl~BYoS>4p%7ipT`%38~|!^bB+eQ2Qfxolq#ZHXrKb~^msdlMIlH#M@heuHzfxl^CL z`O+am4xwj{eX%Rqo_MM&oy0egXy9K`?JX=UZ_v@6B$`MK^C#!gBPUd?xOp<$+Z9K- zpd4D`ihnAWr>R!QIh%hCiGI-W_=}_85Q;2KpXB^6<#+e($*9$`p{+SaU%CND@t2A3 zPq0`#%_I8#pFz$THQw*!3zwP>PI|t zXcXfZ?%O%S>C2xpbnh@rSHC>$5YjLeVwVg#)<)<*g1*An@{G(Q%mI6CqnV_&~OJkmg@ z?h^WW?$Sc_=2|uyZ$^wpM3BH>wU1~^qZ(x9;xxkp5A#)SoS1T%nma@29c8WMzZiPu m_A%gPpas|h#%JCx9Q^~phlb=fp|aZm00006nP)PbXFR2Uhh z!AoddWf*|r_dn-MGD#-Mq%)JGILTy6NmJ_$#Y+{mUWy`aDikW>x~QO7UAQc$#S3&< z(XC)z=%Ugf79+LBS`BSN(=@Sd+6LNOnoC2H&Y5%0|9_toP!Zh-K95mV{*U1K_xiKN zeCCIi#=0VEKn16YOA?|eAxRSAYD5%8*f7FXL*lT?^8C%|sqxEC1*P`p(e2y1isgJigGWa?O4SfNyG!-`;x!R-I+qW86p9^wU4xmvIL`F!BC&N?>u^p;9PE7j0XE;hNhZfu zM`u=7NO0;Gg+0yRucb^_e{_{5#xQe#w=w>~}Lp1i-;n_E@Noy|P5IYZ#_mup83 zv2^k@miE{7#oA&c7Z|Q;o%&Sy*Or<`&f`&%miM!fK3lLXC}zv&wRH8x2|oDf^f#N}%^QLGijDb@-tYd1)Dmf_ib{3+PK z5noJCKutA{3B#DKd_B$vh$`X)Yb~lN!sZ;6k$#%KeuXHUr2?$3_&A^GfSM~K=O!vQ z=KE6VCd64p1W6ofW5g<{><;oj4^qlC5cnxp=Pg&}JXPe7QC0qnpZ0XWeQRlYukTFB i`FdU9Q&w(ib0000XWdO#1@0TxW)27YRHjOiB({#fm&N=PyFqwyo$v{-tKv9?%^TG?oEBylm5q6^& zI`G1Z;6MtBpi~)Nw5g6VS+!x=%-Yg*#hRo!H7#kr~q z`sw$++m{#$&Gq*L5_keUh4eh6<6v11j^kjP7M5k<8Wz$tunm(|ZL73iym>-T4)+y~ z9U4ibVgmrE+l{31P|DjglM1Okq?AbI;Yi7^`QHX|)=p865B4UaJwBG#E4WhfOW_ue z9?fuNahV718^v`Li`QtlL!;NYkx!+VlUP26Exe3jw|R$Kh2KA z%;goNR47lwCWs{hH0nDf6A@gc5JDi{xiIf(u7RdJgy!SeM4Bx-fK=-C3~;5wRf?pX zB~h8i7dp&teU2{|Oop-X-?KBx5Zx=-}qqqi%0HHy_^|O5)So{9@g%l>Xg67XkMW&JVA4HiSXb7 z0)4|2XFoS}fEV8VW;7cQpNd5Xu_c7M{^o4ff5d8DCNh2!t2{-ZN3fp1fn(YY(`Y}Y zJ@wXci_)`0$6|)I)E6y{zTl zf62>aQ%58FB9vPWQYnIdL8bUDJHKBfeDHb9KR!nDJJ>s8l;-lxhF)jINF4{z0ZdzI z<$8#>99`e>j`M^IP*qwRZN|b60Qv*PZ_aypNJ1 T>j+0@00000NkvXXu0mjfM)Ra; literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/telephone_error.png b/base/resources.pk3dir/gfx/icon16/telephone_error.png new file mode 100644 index 0000000000000000000000000000000000000000..d3ec3a110d943808070c97d392ffdf5ab5f2d617 GIT binary patch literal 884 zcmV-)1B?8LP)=Tne){d{WWFc< zLn7LqM=emnsA7B{*Y)vzAFt`+x-Nm^Vww(~)12U`@&4lyxWV%KZOh+sq!fxrlX2#IimnVEUqy()p{ zvvsRZsIxSAJ#O!fM>}X_bD3BsleKYe)La(V7mOI11W(tF>0I{sk)nZf&t9EwLNWo-^f;Bf2G8^p5XEUs=cUmKx3zc~Hb zxfh?H#ir%-TVM5dC*!AbnQlA-@eck`TbrgcJxt>82&w&93JHg{c+VsJ%|7|c=a#cm zJ3rW;i(rMpvPncN4tRHOQmstU)sw{3rzkx19C>Gkz9aF}*rTt#PK$lv-Dh=hsDCV# zOtD$>F(P!fS)j_+(if!fe-fIPx%AN|#FGxOTA5<3Mprs{nwBsvO;7C2?HboN_i4I4 z%*#ik|jeS9N$LBR6rP44VBIi}x{ z>>WlLS5a{od!~eVw~0h596d3~V}*^QwAi#XJrBq6DD-qt%tV+-EKnL4CEB%(234>^ zl)tP1f;1~+28xU(S3*CYJ^p~Dsyu$?ou%Bpxxuzb3^4&Oq+5Y}}oq6n&8)ZMOv z$RfH4+FeEsZ7w%8oE_1rJ8M&$Q#W7E`M><0=jjN$2)YUSd^|Jb|L|Y<;Cx-SDg8@L zsyvH%V2YR_aZDJ-#Bod%goI&;D~3o=Bq|2nUENs9=N6vzJDRJfjvj2wcD6LIOU>9N zYN#4whKM3+hzO!aEW-HY9}Pc;n>qi%#;R;4m1H)*f)nA&)OGqF>t$?WmO~G><6>pv z>UH}1_Axv>Mcck+M3kOvEt%H6^}gqUno*YYSl?C(&Z8h@tQTT_8l6K#QA-d}N$8cc zc4w20Y&}jD&-3u!{qk2!xFQKPyhM_tkM3t9Do0ciHB`Zg;#8^e3k(g75pJ*HqL|fN zoA{Te^RM(~?4!oos$?dUZAq3_dP{RTmR8n?oZy@wqQn9xpLv4r16?{ly*0JGwW-%~ zzn%5Wj9qV@{bBIPBb_hxc6CsjPO-l^!9TtA)p3G&o9@)7OpMK(|N7(CpQ9u}$&2rQ z-`-f4e!eBsNF zGe@M3$T=RU@20Qy2wTApzZXx}9X>Jo-sPds&Uj|V+vhIGiN|{qe{C6^t<@asPBSpr z&&h+YBBqE6im`Ip6>xUkNrB#1PzeCICn%R2;N6GNlZ1R5cx)W)^NDY6N8gP8=;Y?Kl<0l;wLjXh^p* z{^tmzv*T7Y4*Qe@QADvA(blvFaXxCst<{h(E`CC!5rK<%sObRxU8fk!4>NLYjOMwQ z&38=AGoD(00000NkvXXu0mjffn24? literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/telephone_key.png b/base/resources.pk3dir/gfx/icon16/telephone_key.png new file mode 100644 index 0000000000000000000000000000000000000000..cef5dec4e701270adfa86efa01e31106743e40cd GIT binary patch literal 881 zcmV-%1CIQOP){5M;315b@&8vmiw;+euIl zf--d?USyksqoac%ePLU-rfb@)Z>($Qnzm`1=E?K&|NYDk1CibQd@NPv|8U+NzS5Fu zZ@k_dk7ZB`R4}TTAi(nif*`=JdU&2k=z5r{i|hhFT;^d4yC z2~p(sJA=obhafj>3D?sl}CieaC3T@{V2mJY z$F(vwLMieOn5)~6T#Qag09MX~G%Lr44A_G1_kj3^=y8X**+*{LuxGKp8- zB=iF|9`53d&#auuruB=qWFnGIXAVSS4c1y=mbFKl_@N;T4aNweQO;!ZeE7l=lS}mv zt}JGX_h%>0qpGMXADz4O)Av_%I=--{`M-_+*X18R*W&oc8tjeh^6#hpo5P3SR#hxj z<-N~->+bJN&Yc*{)+geP^mfGQOxirPbMIID;w4f8r`TUzAlwsn?%%Dh8QsfT zc4hzS8^`;4;_)V8u^2sVQR*Cvr*?7|Xc>47aq~EdPQ>4(C3`R$DQ%y$N6)>l+5XvzFFbD{Y;D;gk#Z`6ebz{8z>M7L! z6U*#z=W+#8-X&(+e48H#zxnyQiw-qa-^X=*y4ve7p@XRMy5{IR@eY3RD;y_D?wZf_ z{kN#JAH}V>6x>@vjYG}SR4!k6ypfI8ClC`NA`Be~up$qM)TNpFV}~E_zQhAfB839g za+$}gt6x%MsVdJhasJqFV{7VcWozG^pWpc8^w;yh@C^R|1}DVPjf76&ul|g18afxD<+D5$i%kT?-B% zh@vP$#cHiX>433~qz+9mKZ!}K#5BpDef?HZT>9a0-hb~7=iYN4(KHSJ^Rb<$@7Hi{ z+rR>giGxM}O@%^(Dv|_2kRVYMD+1jMkjny;N*Q9gf^XRwJ|6wJjSbYC%HKs{XGiijES+(ecUJCqg00Hn^;u$HE{MPeY~`BavyWTNT3aSPUzc zErKkm7<)U7*4D)s9E@P$;yOLx63zinz0b)K@-wTEA^2KUQIZKtiVz0RhelSye%(GdXp2NHfS~7$`MjV6c8=5Hq5QQdQ^60A;4?4hz^4`um3= z6!VZp3E5-;?5m0Rp^!&A<8oLTkB9RzrfR}ZMZu@@5M>22U2`lX1=zlI4O-fo)DIKi zBdPBN^?mepANeKYvA%oP)-G=hhnfO#*enRv8UB*%%Dp$JvQ#6R%V1n9$j5sa8%KT#rtVSKZ2$&&i&!z57YeEUS@je7Df|=%WcgZNzMqE z7`%(}Od8>E7=FJWcDo$|0|Uq;KcREaPBb?+!R@LA%T!vD$)u5;qfrr6Ln`+TFP{&= zS((P}g9mW3rw`fqB>X-f+S}Xlg-_so-#PH96x>`8hYxljkw_fT1ITn-CEDrS=NKIn zyIz~QWd};{#?al}t(Q_P7Lm-A!`Bp}6q7M?wO`icDcoP)t23;DWi@b-gt_nl^)UF00000NkvXXu0mjf%`2aJ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/television.png b/base/resources.pk3dir/gfx/icon16/television.png new file mode 100644 index 0000000000000000000000000000000000000000..1738a4f1061e2d50eec37aaca71fc4506daf737b GIT binary patch literal 696 zcmV;p0!RIcP)H`oW|{1}@v@LQ05MEhB<# z<4=>;WR@@@AqLtaC!HVPednGQ<4lg$g~L5?&-dMX?!97W^xd6Eo$oxkoJ>mN{Nh?T zKGK`#ALG)s`^~4%wdc0Bisi*@repfmSR`f!P$zkx{T@z?_SH!)UcKGidA1{0C>G0$ zA7?uRzSSI_Ih89GO69MgXFKNKK98zQ zodDp<&Bv*(&J#KH@!=2Cb72$}=}dR!3fra9w=bFS)4LbZ-g+@J1_uWp0QaggGoz)Y zB>|wSc<)(XUsp53%urPdg~G$}@$up0E-(~ceR!Hy^s(H0Oy=QCCAKYOhW5XAsPII%aO9W8L<_45+Wpm z3J{2(s?-F|Ih+_O=Jc>IDrA4Q#$1Wo2cBk)48vLrVrKOB_giagE2{e6@ZQ&E?>*UUmP{riNq~)w4Hgy_YKz``%3%#1@% zpUUhS8NL$7k~=>;Umibxu+IO)Jr6uPwBy#T)kdS0%uY|1CO$ivikSgykbFP=Yx&fP zLmMRfM~@7R+)}DGTdidF!nxAqmv5&4eF4BjPra3?Y~6ANv)tLUv*i!pI9vy~`@ScJ z$~(7JTg`Uz)1`Bz^WVIit}`110QW!gN@n{=p{k)f@WaGZIZa!PRJK=}tL^sBGn3_u z-@TXqvtP`Nv9Yn|fM?caW=1}rj{sDa5CV&fi)v<=8LCRN*?fL{eEe9v1{^Iv_=5cV zXl9@WAsC^p(fo?1tzf|N$%99MV-8?&a8UBs2~PeCchy*^d#=_!-5^8)4)ER!^lHqE zTnsmE7Gie|PEzG+Ev1nLA`v3j1Dpt|N?+i;$7>I~J|~Fu;6GNoSYQnn9D)H}f4Zq|7y4@}vHPWuJni?8OzpbL7CAy!iRU5wxN!S n4dUShi40T0&u5wX=ok4L@Mn!_V?Zap00000NkvXXu0mjfm9%nh literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/television_delete.png b/base/resources.pk3dir/gfx/icon16/television_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..b9a58602519e2274883b9a0175b68dba4904b063 GIT binary patch literal 810 zcmV+_1J(SAP)HO)t@7&{J%4pS_+?(Ixe&5MCN6d@^ zZ=Oj#IkaObiX?q$@n&J-*uEXxuQ^kQtmM}|CPcIg}_;{=eF!I8| z-ooRLl^XSC>z6AtgO@Ixjqfv?1OR(qJ&_t7%9Ye7JwHv&72>$TP;t0aUu!mh{du-9 zfAL)W&;Md(jE|4M1H5%#W@cow*$_Zg@!nG|m(|QLGgOs&z5edR#Ke(k12|lG={@=P z(9A#$yf=JP!<+XUO$7t)p5AvDI1&J4G8xHk5d!%yoTzcD>R72d5-)@T0pOeyXlKlf zbOe1{g(&zNZpF$nDjk7y4ySE!TUrol!*|va%(DRt0YV@`U~~i# zKpe-!9@way5~JEuKoBtkVEF1u`sY6)RW4EM%`x3Z+pntP6ug0YPtAEUsQ{-&5I|x6 z6i@$go?ZK2p}T)K&4q8+adDE#JzcK{07;Utu11^~Yq6oe-Dg(_Wz^~Qb2}z>u+u_)-Ebb7&PWv03^l>Tc;N2ur2G2e`LWKHqN6!NFFPZE?(S|X zlgC+JUgp@fYmDXdIOix9i(H+XW29#*jmuxL<;&MtZ{DT>)b537$gQZe1?R}+a=f3- z@~A4RN~KaEpU-onw#Jnoz9YZAhbZi#b|>L_Il%BAikUGwI%=z{t9b7_*UUEMXCG?t ol&tVD34apuef>c`n7S>00b`kqs~MqiE&u=k07*qoM6N<$f?b+?G5`Po literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_align_center.png b/base/resources.pk3dir/gfx/icon16/text_align_center.png new file mode 100644 index 0000000000000000000000000000000000000000..57beb3813973e69f535a822c2f0424fa9f560303 GIT binary patch literal 234 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-%s@pN$v(Kw&{=X`^_fnmU^23D6T z|NkHVz|K?O{7~QE-_Z@zCpI>Iv^P{UFnE&ke;(6i-d4-w%bHR;j1|AyZ#v6S(amDc zlKy{I(;D%Nuye{ncOLwezxwWez>k>{<_3S*oiFG7{Xgq}=)co{r~lFaH2=T-_xf)+ f9X!fMH*zv8ak(u6{1-oD!MC#5QQ<|d}62BjvZR2H60wE-$h_H=O!(Kw&{=X`^_fnmU^23D6T z|NkHVz|K?O{7~QE-_Z@zCpI>Iv^P`}`P2Tg^+n4;W0%&Nn`h_oB zXMCTNA-w1R;@9m5&b!P``2Amf(pd!#&g=F^W;hsZV)z*wDqmKyKNDyjgQu&X%Q~lo FCIDq2QD*=E literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_align_left.png b/base/resources.pk3dir/gfx/icon16/text_align_left.png new file mode 100644 index 0000000000000000000000000000000000000000..6c8fcc1165a433617355ac5e182d015b389e9296 GIT binary patch literal 209 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-$h_H=O!(Kw&{=X`^_fnmU^23D6T z|NkHVz|K?O{7~QE-_Z@zCpI>Iv^P`}`P2Tg^~Il~8@dITHCPA-{a3!-)3Cjx%=yXx z_>8LclV7mqn+PY^{qor&o%8>H%d3``{~Y#6bGV5yoI2touNPXs5@;QRr>mdKI;Vst E04%Lf&j0`b literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_align_right.png b/base/resources.pk3dir/gfx/icon16/text_align_right.png new file mode 100644 index 0000000000000000000000000000000000000000..a1502571c99fb92b1579c3658bcc50c5976b8e7d GIT binary patch literal 209 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-$h_H=O!(Kw&{=X`^_fnmU^23D6T z|NkHVz|K?O{7~QE-_Z@zCpI>Iv^P|9aJcmUe!yIVina{lp#RFZdm6TTlr;aYZ;9)u zJl|<{@VEV{yZaY@Fz(E|@awC#5QQ<|d}62BjvZR2H60wE-$x=jq}YqH%ujg@wF_4MbQj@OPa$ z#N&HdE16k1*nCBr=}I0g*DjHSSAtwt4sItn>RWmQ;^L}U19^Fv7BBYSby+aOzJ$YL zj>TS~{$Ts#`4N9lZ=Cye$+c~_4@}ZK$@9WkqvnrvN~H0Mvqt#~n0udf&TzD|;=Hs* zf<-9y=7rhpPXE4Zb^}|6b=Y6y(;Y{!a!g z@UQp#@Aw}>L3(}s|7f5BUjeuKZvQRjV<2U7yvu*H{aAbvQ6K!@3oKzW z-{Qa8d3gae1^)HE{~f^!v<1}u>;4xnKvUpW540I-w9J3a{{r=B3T*2g{_BH1CtaZO zpZ`6V0*V5g1e5i;`_=Z#_e=H*@8|93RG@lX;D!K7TKswwko8{x0000C#5QQ<|d}62BjvZR2H60wE-&X@N{tu(Kw&{=X`^_fnmU^23D6T z|NkHVz|OPW*vP=;@BgD8WzABvu@M{$HPs!^U|F=gR-} z&AETiZeUz-oG szv_+eu)PvwoyEX;-Tuf72ZK!v%2xjJ(h^EWKsPaXy85}Sb4q9e0Nid~c>n+a literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_dropcaps.png b/base/resources.pk3dir/gfx/icon16/text_dropcaps.png new file mode 100644 index 0000000000000000000000000000000000000000..dd65786a7be028fccac7dd336804281596643f66 GIT binary patch literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmUzPnffIy#(?lOI#yL zg7ec#$`gxH85~pclTsBta}(23gHjVyDhp4h+5i=u@pN$vu{fRl=l_3uX4QtyMyG~E z2bbS{CJJSW*BHcfl8hTG_(hr>Lqe|nkKbQs_~+l>*^DmDAMWj~mUJxYIg!Y)N!CM> z*|4K5Ht^-f_7L$FCexixdjt52Tl@RZ*Uva>Q1k4JWQaI}X)BZFgk#kXYh2c7M=Y2% zb%9wMqv@UIPmXLQ3>!P=&XsNB&bzy-Rg&!qLxqHkn_JS2roP0D42$O5*ZZZ4S5#O3 zS5L7v`uFFj@zmIa?CjtFpP!!}@t6B>{l7ns$F3AI9^EO(U@`aN<^{{<{s#Js!PC{x JWt~$(695Iyd-ebT literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_heading_1.png b/base/resources.pk3dir/gfx/icon16/text_heading_1.png new file mode 100644 index 0000000000000000000000000000000000000000..9c122e91e358860733eaf08fd543e5fc585d4cfd GIT binary patch literal 276 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-$x=IP=XqH%ujg^j!|20W|*-XbO@ zAtBSd^khRzd{=pNv@vN)9uZDqGTXuVPf6#I=?;x2B`Y;1YQMI>>GxvE??vtn{c>{A z7MYxUVrui2JTF|YR&ldntL8M3{q7no52$4`vIX;r@S8@YTFOM5*~nV4Gk-UYI5L$} zDw(h9UDksmVjphbEsSQ?UdGUxU4Htk{EZoY&3@-Y5*_;Wwk`ZAkg@!FaC~ii{N>;; VD%(>GD}XL$@O1TaS?83{1OVXtVO9VD literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_heading_2.png b/base/resources.pk3dir/gfx/icon16/text_heading_2.png new file mode 100644 index 0000000000000000000000000000000000000000..fbd87657fbe001c0a78fb095284fffc32e739497 GIT binary patch literal 304 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-$ROXGNhtQ`{C(%$wdeB3 zGTnLdz~IMJtNg?T>Z(s;oVU0)KW5x*9xvq)rPF;` zY|Fc4&#rLa>Txf#@y+aKf+ac0%`STzAI(*qdYo^XFH557y+_x*JpKO5^1S9?c^6}{ zP=+&OVHtDUrGNmdKI;Vst0KHFj AM*si- literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_heading_3.png b/base/resources.pk3dir/gfx/icon16/text_heading_3.png new file mode 100644 index 0000000000000000000000000000000000000000..c7836cf09e4565cc76c13bd14c13971c9e093c40 GIT binary patch literal 306 zcmV-20nPr2P)wEzGB literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_heading_4.png b/base/resources.pk3dir/gfx/icon16/text_heading_4.png new file mode 100644 index 0000000000000000000000000000000000000000..4e929eaf583f10cf50eb1666ff6530b9d4cc7915 GIT binary patch literal 293 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-&H?&;zfqH%ujg^j$;1_G=B-XbO( zon2btF4r#xDw?mmvtwaL3R_~+Yz66*rrQmiHySwec#9a-mn?F*9`VcnzTNDrbNY9( zxOA;CUb9S|sk-b7=Pc<<>lMA8+|AaBj(NoLhh2`-;+F zenR#-z6;(Syt?;Ub#DVE_OC literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_heading_5.png b/base/resources.pk3dir/gfx/icon16/text_heading_5.png new file mode 100644 index 0000000000000000000000000000000000000000..30cabebf7445e168a0f31b0ed68c43d54eaf017d GIT binary patch literal 304 zcmV-00nh%4P)ZVg9Hj*!Zw zxkAM~zCH&l><=6QeDdgV4l9hop+%GWq_IPV?Z641X8iiHrWJUN^2}hSiGjhsfbOLp z?d`9_MC0P3jVAVsEwEMMb0n zB0~XIzS#Ls)0t~Xm4+o)ss{0VQa0sa#lQ zId*4emlM`ngv0=W5j91YWvvw=LS5IWstQs{pJiG4EQ-Qop69~#iqI8W2WgtxU#iXf ztEXoNNs`zvs>G@%#?>c5KMuD0+hH*s#$63W7TOpnMy0?=cxd2!k;mO;x%LEZcs6dg zfiV_j+#shGjBXInk>NV>r1Qxre!Ic-t~!+zPb((S+IXVgZxH;I|A62L)aki)c<;-^ P00000NkvXXu0mjfr4WN8 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_indent.png b/base/resources.pk3dir/gfx/icon16/text_indent.png new file mode 100644 index 0000000000000000000000000000000000000000..9364532344e4b182fc286c4ad78c738533335d73 GIT binary patch literal 353 zcmV-n0iOPeP)A?80v9Z^YZA8as&YaOiG2qAVzYLj+o?N|k`)kPFX7%epMT)pIgD?z$ zz0k7x#eWfQHil2%e>0rE^YzTbTVLW%P1UySD{rve8ZZphV4}^gtsg#oV8j^<1D2Tp2_^}JGDwbz00000NkvXXu0mjfU=gFa literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_indent_remove.png b/base/resources.pk3dir/gfx/icon16/text_indent_remove.png new file mode 100644 index 0000000000000000000000000000000000000000..1651b074ebe5f830c23c909d04ed3282cb8892aa GIT binary patch literal 351 zcmV-l0igbgP)$KO_&&&86Lj*&d?hr!$_C#5QQ<|d}62BjvZR2H60wE-$B^mK6y(Kw&{<9vg>Q9!g~ne(gm zmj4swoA@7?D86%i^8WzK9JM17E&sp&Z#dpHfz$E-U9ks&4?Z9Gyg!%0k2Q{M-Tz#> z2OnD>vrPZ*#{EHKLq)>Jcx{H|Ovdb&|4aQZWSipI{El%e^Cxx{^9vSw28s;a3IDB= TS1%U=TF&6<>gTe~DWM4fm>N^1 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_kerning.png b/base/resources.pk3dir/gfx/icon16/text_kerning.png new file mode 100644 index 0000000000000000000000000000000000000000..377def645978fa0172693189c69393137030dff1 GIT binary patch literal 495 zcmVn~4Xim_?2SqtKIRdGvsr_+rar?uY zI#~heudl+IuL_?2zxRcWA;4J<4y{sW!t08%R{DH(tg2Ko8<0hyVZ0w6Zf z$@_zYgZG2j_T|^w9V@O*gF1P?yuAE;adB}40RaIA6a&)J(*qI`5*#8TA{+t&0usEv zz5fH9>|maANho&4y;law=T(4CPEb}>{?Et9Hy}KD6(BY@H}`!uHa3*N1Ub0?=w!H`EG;b+3=9nFfljUmI@v)x_6(<2Hrh002ovPDHLkV1nwT$M^sM literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_letter_omega.png b/base/resources.pk3dir/gfx/icon16/text_letter_omega.png new file mode 100644 index 0000000000000000000000000000000000000000..5075ec6b850079097edb17cf4ab7507341751067 GIT binary patch literal 541 zcmV+&0^H(oRrRq(~AWF-B$wEEF_5P#dC*3bGSjS@Q@3 zQei_)I)gLJNbX1Y+g)hTjNKG;v2HedeS80F@f!fZ@EaNa9MBsQi^ldO^2n-_SKE}$nU7=6ST zj%A^9DHM*qLw7)k76O>v zuTf7_`5Xah0F7>*TE5D_Ohm>%WPlxq5|oWTQo1!ZFY##ULV=nYZt%OgV(e+qc_c%% z{Tb=j*d0hQ#As@8^JsiOjVq@T`KroCpN#z>0aw`)sMPvks&{eP44e@es_f5n<#dAT zSWmKTzGS}67BA0|aM=<|oGKoO)7DK9Gyunu1hxYSrcfFtiN^QR`AZ|)A`B5(w?wcI f^MD@U-?s4sJZ{q)Y&_-b00000NkvXXu0mjf&&BDg literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_letterspacing.png b/base/resources.pk3dir/gfx/icon16/text_letterspacing.png new file mode 100644 index 0000000000000000000000000000000000000000..41390f54901f8246e92a229741bac31b071c3eda GIT binary patch literal 503 zcmVIRgTm)FDCIXO8Fsi~>^CdGH3S3%D0q5${f?U>J~@nHi9roGbuh1D(9z z%gbv&l9L^@wYC4t%gZZ>i;E{<4a9_mgn)>M2nV2(9o*gB6P%r$|C^baIl$y)WMuA( zh=}axz-dClyIV_J-BL~b4e4$0H9{wt{tzw%sTk? z|AgJI|M%{A^}l1=tN+cLp8wBV{P9en#AM1%O{<>miNN=p706cqf= z&d&aynwt7QAtB*^WMt(3;NakFtX`O~`}Kc{!k}-*E6NOL+wu}_Kze%m|HQ<^|IyLW z|3gAT{`>m+{&#b8`;XUv+BMH8b3yXlhtDW7AZqG8xB>qD{{KBZJpMa6I{vq^vifgi zWb|KKTl>F?ipqaEIk}Zs4M>{#fHE&cPrXOJ0iF#vu4T=C_}`=9##IpC#Kh#kuCDHX zH8r*W^78WkB_$>Q3kwV5js^Ab)0(c;*G_|Ivb{j6W()(!!2nMa(hM;Jfqeh~002ov JPDHLkV1nKcst5o8 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_list_bullets.png b/base/resources.pk3dir/gfx/icon16/text_list_bullets.png new file mode 100644 index 0000000000000000000000000000000000000000..4a8672bde48f806d3d4d37db192588a9aa3eac10 GIT binary patch literal 344 zcmV-e0jK_nP)PbXFR5;6H z`2YVu10|S&DhA}te_Swi*Xsu$nk)lAnzx?+_#Z@r_~qs0*+Bfiq@?73K|#U)?Ck9S zsi~>|6A}{sM@B~e4-O9gPhA%bd?2RGd{of6>E(lvp1b6Ep>6&12TPB<{a?EDDL4@0 z;^ML+A|n0=1_u83^78uc?CkvC#>VEqiHXU7U0vP(YHDhzff&$ntDt1@;|H#l*M@2! z+U8#>h@W=vfpy*`^1J}j+`sMRe-I7g8yOj8Yin!&S5Z;VicFNp}SURRVGD{CSNFe~ni^^#wyl5uzj4je z|23%2?k#{x(*%mqe9M%mih+W%ElRQ}7!$^91> z7ymCLB=nz$hvz>#JNtiTW@gkt1Zf0eyP_){bPq%T_kY#2Z7&xs00000NkvXXu0mjf DNYA0= literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_lowercase.png b/base/resources.pk3dir/gfx/icon16/text_lowercase.png new file mode 100644 index 0000000000000000000000000000000000000000..382a102e3d5598e294101172dbf2590ef91ddac2 GIT binary patch literal 709 zcmV;$0y_PPP)SW@7!&*@Ou&cdKUy?8|jDh;r$)X^FHUK0Z9A1+9pG2o*-!S zhM;u^zO3)BuYZE33E^Si48g_e7*uSeVbcIDy9BkHAFUsaL+OgJJB~W8e?K;~3e8vy1y+KZ5djw-d`1PkiUU2o zE~!@aq@v$A+XDOCER?qeXvbra_7O{>mv@!7XuJYWxue+EvBIR>t;A9Et@ZH>)ZUFj z()03Xo{1MF@|-T7)liEvXBc}JPM2ypT4<6&V$8)s<7MPra{ZvXzU(d@C!7&ndlE+$ zvy6;ZPL$F>Vh)R_uCIcso^<`z_3vf4sWW#3G|`oI>Vy8INBmQ{J-ok)6`&kmMOFvL zB(hxwjwu}oqr@7<_VWQIC4lP6WHtiJ)33-jE+f;xiKy;w`s+%|xPZen6W0f1DFIYh zS9&9i-bZniIU>kxTSAs$335va`q59Qxf#Ksb`IjYMOjh+y{?GrvKjgyb~FbQx_W7ev1R)}^n&NG}0M00000NkvXXu0mjf9u`O1 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_padding_bottom.png b/base/resources.pk3dir/gfx/icon16/text_padding_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..4880c43a14ecc3cb1e29d8cddc4f387a57743615 GIT binary patch literal 237 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-%s_jGX#(Kx>}(2>uk*l_t@;dN0EviS{mT zvGu&K!k84#EqwClM$Vqeq31P!wKX|r@41%rr^5Mj!bSCsndhIXFx>q4hRt2*@LPwH h>8~X2DekW?X1^%zd1ncGXCcrj44$rjF6*2UngBWCTFC$a literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_padding_left.png b/base/resources.pk3dir/gfx/icon16/text_padding_left.png new file mode 100644 index 0000000000000000000000000000000000000000..b55482eee4e7b0ba2a88d4a46005567336f8ff7a GIT binary patch literal 271 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-$x=;`7ZqH%udL_;nnLjl+Ll>Wz( zIeQwyH^i^8ZQrmpJYqwvw0?qe1+OEEdf{i?O@iV*XVXsY`Ty*&#mE0=XK;luxHIb9 z4YSo}n%D4fBwGjp1p#q9X9h{oRCy;FApL49`wQp091V`y_iGV}U{9{r3-4 R)q##>@O1TaS?83{1OT)EWo`ff literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_padding_right.png b/base/resources.pk3dir/gfx/icon16/text_padding_right.png new file mode 100644 index 0000000000000000000000000000000000000000..106edae52ddaf5828f2c13d9a3f0b765348ca360 GIT binary patch literal 271 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-$x=;`7ZqH#X?&-n&<1H*t-4XiFA z|NbBT(EiX|;vdt)=eL)BYkFIjmhz*Y`Q6X|5C6~m|6fsU$^Z73Y=>6wm*9Kh(DR>v zbCQ~}+3o+zcLe_a7x%GevD>fob^b$n0Vh$N)FaE}JsaQGtK1E*H@?HT>!JMN_?D)# z5k5cKbDC@?aVGq?saOBXe{&-H#$Ak_jf_{s6YhrpH>hE3KU}$i$*n6{nBfgu*1H&+ Sq+p<989ZJ6T-G@yGywo4ifyU@ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_padding_top.png b/base/resources.pk3dir/gfx/icon16/text_padding_top.png new file mode 100644 index 0000000000000000000000000000000000000000..c5c45b2d6e3485f569b4b84ad4a6eca343422381 GIT binary patch literal 236 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-%s^K@|x(Kx>}@HS_I0neTeWy_X$ zzlR)kJLWKV?CK3#{b1&`=hMT^Ok|mL=jj3`8~2v|+#9v8zU8YG>i!n;jaA|1{JRO> zi*}22JWI(vtlgq0=VdiDGEr2y=g`$KCs8iH88+V&u75h~eC}h}%?j1kvz#}y_po2D hSm!GL?%~(XVeJ1s?|cxdKM8aRgQu&X%Q~loCIFXdTtEN- literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_replace.png b/base/resources.pk3dir/gfx/icon16/text_replace.png new file mode 100644 index 0000000000000000000000000000000000000000..877f82feae4e68deb2af0b8a8100a141e4f9668c GIT binary patch literal 691 zcmV;k0!;mhP)%W!&uf*aR7m=b*g|(kUJU9 zp=n%1olDSG6tD^6Pm#c6n|B4fFQ*MV1`x;`99zMDR*0#E+F^m|oe836+P7h!>#yE1 zfI!Pp|0)RN)PgnUO$R@72rPJU`eo0n-Y3TD?vS-`EG)AfK{?SrAt%}ba;()aIZ6Qp z@}w&6x|k9*7g8`rL*Kdi8;ED#;QEIV91l(YIPowK+e{Jd0T~0&6kK`z6@7djhdf!w zwp#S^9d~>P!TC5WQwj!Wi!>p*WY}^u%h{eQ=zmnefl-ky`!{2#b7T1JN1S<4gx>S% z7mb%u>(n#eMi%C6?_t0)6t-JzDG!NaVz^b*qE`c@Om0%1= zpr*5B14!3kn2^D}|Au;ZM%_q;bhY%VI5ex^Fx52YQ--nur0X!-_-*q03322ghy(&cNNX?2}d-6ZV@ORut;!KHNq*K6#He9hTK Z<~I`7qRvVbo(qSIUSEps0Q zUAr;NZG^#_4#09w`|BfW=BSyYW{#RUYUZe!%aN8eSM+R$yO)9~xWneh`0_bwJ2z3R zvrY?I6E4E|7xT1sOU>o5-Te;Mw5*|^dcu`kX%q>;$_F=tdyg6kUl(HY>9E*FQ*c$& z3MlB3C=DXPUx+Ug^$VQ5Sw}K5f<(}Y&`cWm)^1Sn6&5VGT_T#eM}w!xAf8TiNJh=L z+NwumgW~8dELd=DCv~^pI^3L@@E91uoo@nRM;W|^4AqxbIW|Xz4i`!hT_{9glI)z0 z5%aN;^zQW$v0wqqva>X6a+Y1UwM!GBDKZu?k-~2uQ`kzx6c+#6H9iB|X|uV2x*{9^ O0000C#5QQ<|d}62BjvZR2H60wE-%c=IP=XqH#X?$N2_%qYIvnKN~+W z9~Ca*U!vP_U*I3(>?ZD`Y&-c@{(mg}&-h1dLFs{j0GSW-70)XEtG5VfT;0^m6lQ+J z+U3u8W~~h~6Sg>h-hYUxlQo0ukSx=`-AtkqjK0A?{?B(bVDN36-+a7&HXBFuBYQFJ z7+INr(vG4WNx=!554>o2#>TpUpG9^D-v)~d)+;_bGW>G+5&iVi|1&@rGI+ZBxvXC#5QQ<|d}62BjvZR2H60wE-%c@9E+gqH#X?$N2_%qkv$?&V++! z-fX$@sb%KG-5a$|R8J4(Tcmu7`G0cYgxS-++3#dN^zA^J(=P8r|6lx9G_LLaZ+v5S z!d9iC@)!RP{FnQmdw#}3Ee(C$|NPA#|L6YmR@fBO9w|C7oMMQ$vc`Tu(RETvC<`(>OPJ!ieM-fH~m>7>jJ-3AN;KsG}ItN_H<)YO~+biscK35gGaf`SIg^B!*iYEReM4Ple+T`TtK`;KS0!apVx86LEKKJ4Opo2 QTmS$707*qoM6N<$f=73^s{jB1 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_superscript.png b/base/resources.pk3dir/gfx/icon16/text_superscript.png new file mode 100644 index 0000000000000000000000000000000000000000..2fb2a7c7483531a9f518018de41607eff409019d GIT binary patch literal 421 zcmV;W0b2fvP)CG+sNmIhtD#~2^Z#UfA#v8j z3n}v+J-{%ayuAECadGj1+}zv)X=!N(;^X5L!o$N4`1$!AaCLP(08(RLajhY2(!C4j zIhPDD3;=2l0BZh_l9KWtsCfcN45+yQsCj{njg5kJ(UkzF>T3&3GA;-hCSP#Si$AM? z;RT@04nWQSBO@dK12q@GYzATP)|&^?=RW+OJnO;#u!(m+;0yzxvnK=w2L5+*bNdgp zS%Bnd1llYB((K~m^54kFXadOwfSe7qxxm`m`oDpJ!G8q>1qY%G0ND%;umTWYQ&V#S z&;|b`BqTlv3JMw!GyrPz0g$tSnhk(99{_4T0MvYdi;L?33k!?E;LJ<_HjJTTC#5QQ<|d}62BjvZR2H60wE-$x?CIhdqH#X?$N2_%BY~9*Y!?2h z{rUe=9fy8l?U(-(m`sFEeV_iPeWNmK)A{6xz&-Zw?GGia|0}^&^gUfcv*1X`gnjmc zo{g-_np*x&^x*npDC+Wt-z8{4+sXs`@BiMP%+Rv-k;3)Ae_+S0!x%EHv-|4^N|MkDje{TP~{@MQ}vm3aX7|tvG V&AV6mZa&bt44$rjF6*2UngI1lb~69~ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/text_uppercase.png b/base/resources.pk3dir/gfx/icon16/text_uppercase.png new file mode 100644 index 0000000000000000000000000000000000000000..8dcc2dbbb212b01abbf346206e933171945a3257 GIT binary patch literal 747 zcmV1EDu<7r(0?-_Pg!d!8HsIpt%b<}90x zDMxvzT_Vm56BPEut@7@FlT+>#73arAln#?v$sox)-W#`G^N1+86$@nrD76#CNgD|j z_a_)?WscsChp&t$aj>1st^u`bs5MqLl#s1q!;FNIJD-qmh$yoHoE}bqTGtMnxgu)S zXoDkAd3!f>k1ywD1<*K?IK*&k2aFt3IXm>#{>qBM7u`^M>Yl0H6}c6Tvc%1Y;s6sA z9HxNuzC9q47QaA@(}c|cs5Q3V_yPIXBVqM}o|o3=U08}fLg$kX(D3@H-r_A&K#NIFG)9+GxVtF9F!gyg1NgI2^_*(Jvebfwh#$UpQ#fHM+-?h|6-K|Xd1IR2c0OH0 zM<9&`ucZ7ZKptw|n0`Bn`>&liW-Rz_^h;c`muxh7$a4SU7qt3QsCVxIpkaa5md$b) z=lc4#I)h0xy5n!C)oc!?VVX~&&LuLtHrSbFU#h5eRzSmKd{gfhDyfxeqxM$cDzr{v zZ$Q&bDzDKi@?Ak5_0H&mj^#4nsvQ$xqLAuQeqv7mt!p*=640^H^*RT)QfvRXQe%s( z7+i6f=Tf+6=R>;!^iz_)!$+%+$3TNee%)QN^RQ4rm5qe|0_Z(bUgl1E<5dUuLu-!) zYFJ@kCg|W5)XFrt1avQ?QOhQAVSp%q1L!72J$+r&(mQKdBHsxbERuIs_xOoQ8-Z$w d$ibbN_z9tvwRADeG)w>h002ovPDHLkV1lyYRw)1g literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/textfield.png b/base/resources.pk3dir/gfx/icon16/textfield.png new file mode 100644 index 0000000000000000000000000000000000000000..d37e7304e24c78f335466b07a898480a26248edd GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-&9_H=O!(Kw&{<9vg>(FMnYC;$IY w3^*un^MTdn;7P{?4C|HS{~YI+WOIxGs_iP%+I;TWWS}+%Pgg&ebxsLQ0G+Tf(*OVf literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/textfield_add.png b/base/resources.pk3dir/gfx/icon16/textfield_add.png new file mode 100644 index 0000000000000000000000000000000000000000..204de72316ac13eb8456bd8208f881939885d6d4 GIT binary patch literal 321 zcmV-H0lxl;P)4KV|@pIrODbY{Z;v_Aj;iCtd* zm+qN?Y5+dG>FBcmjjI#?Z@Dt{|Al9}{`c?B`XAn}`@em0*?$I*DTHuhm*@YDmnZz+ zcx}>u5a`*H`oDiq`hVMedEyd_PqpFyZCB>}M+TcNP5p14ElHdKmO0YjyLTo1Z{L*w z*4(}`0qg>x0pE!-0I0AfxJToE@2(WE%^(`Y2a5L)o#ugxJAn8T$k|Z310)Ur_h~;h TM?3Hj00000NkvXXu0mjfa9597 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/textfield_delete.png b/base/resources.pk3dir/gfx/icon16/textfield_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..c7bd58b21797817803b49d3b2b53323e17fda625 GIT binary patch literal 335 zcmV-V0kHmwP)4KV{At)KG$c#_utJ;JncjQ{ugvi#ZM%3MWsnm-aQTLHB3 hKFHZ17lAZ`!~r__K9H;4^nI0$7`a(T+P4hBKZ7hk58-_j0w;$<(*=f7ic$nT z*Wgd55in08>183j3?S=MAoDDTLoLSL$!_UDxXqSf-?qdd@H%8(We~hQu&uVIo$6NV z(zMY7wn6r5i617ZGZ)-J($xXssTcN*&WujcIDRIp6J4_PqOvJ}9!p6+yo8LmAGS3~ xN#Qq?aIt$6X#&>g?8!V{ znjV^ye=2;qm;P{$`s;H$`x~a}R(xgP|G$RoO>~FD8I7fnS&nXWFMPEjPiNb7^=IwB zO%ASl$t*T|^U-%%8&{}vv|YWQef;Fc%Euzc)I$ztaD0e0suWxYs>%u literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/thumb_down.png b/base/resources.pk3dir/gfx/icon16/thumb_down.png new file mode 100644 index 0000000000000000000000000000000000000000..3c832d4c83cc0f7869a83f88833699daff52fcf2 GIT binary patch literal 601 zcmV-f0;c_mP)q$gGR5;6x zld)?PVHk%KwHXvA{{RQkK^zqPQ*`Jo3NFS)5G+C!og7>$D6NEu!3M;jM7RtZQ)9g& zq2Y3PT)1!{94U9^xG!8xj6)xXFPclGw!?4uK6oB}yu5D$NbE`yI1Hp{cTP^eKY;ujW&%y5(3%q}8&Iu+Z9^2vgn!@=`cv5NLoOc^Y;-QuG-PEVz;+}o zcENrCULQOkUgTneivF3xTc}jz)O*_!j#u{k5_Y%2vSBq76X>=lfe@Sy)M^rlSN41< zFBak9y3SHYoe91;AFxb0c`@LxEMB>3K(+u^@@dlfv)n11o(YQ9DYCV@ysWAe)bA*@ zA?~zt*M)ZwRm*@RfYubyBDcy zzi@ld(BZ+WEz+fP2fGEuIfi0A$28@nAFW2*$}b-Lm=yg4isoRq;qlX-+{iBf5B^t> nvr??6H@Wu&uC1-?2Lp-UJe5p>RuR>I00000NkvXXu0mjfVs`!d literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/thumb_up.png b/base/resources.pk3dir/gfx/icon16/thumb_up.png new file mode 100644 index 0000000000000000000000000000000000000000..2bd16ccf294bd944c6bf17fa0345885469980820 GIT binary patch literal 619 zcmV-x0+juUP)EAdBAPtT3aD}=*%{NbB*ZGcS?IC*5jinhDl=TC) z^a(zA>EnR9^9j#^IEMZn^!id5#SnEtL|{9h>X0|4DCpP8H?Ix=ni&xHWU$qNT21yZ z5^*RX2qmP^fMQ*vP*nzi&BkZ)YfvhI(E`_#urPuk5&HpnzVw-Gc(=*`uwjlh!P+m)3pz5ENXE;8&W2W*v~T!vOF>0KmQeQ*+S#{tWRxh00jSgfv7 zu5dK}P{{s0ADkp>$Chu@w&3}~KY;h%H7W`eKSHGHs{AQG2a)rMyf zFQK~pm1x3+7!nu%-M`k}``c>^00{o_1pjWJUTfl8mg=3qGEl8H@}^@w`VUx0_$uy4 z2FhRqKX}xI*?Tv1DJd8z#F#0c%*~rM30HE1@2o5m~}ZyoWhqv>ql{V z1ZGE0lgcoK^lx+eqc*rAX1Ky;Xx3U%u#zG!m-;eD1Qsn@kf3|F9qz~|95=&g3(7!X zB}JAT>RU;a%vaNOGnJ%e1=K6eAh43c(QN8RQ6~GP%O}Jju$~Ld*%`mO1p`EB*FHYdKr%;k=xO&(k^EfNlSiKZ>5l+xr|%SFOV@6-ysFmD2F5 ze93OiS+LaQym;|2f6tbH%~V`D+ND?vc>4J^KSLxEMifJQ`8>*~y^+pGr&o-n=LJ zGWB(yB#;DR8&Lhqi{0(#wc#SwSB~jZKzIFx`8od>2Fo-Pfe7*M8^q#qw2yTxiXzd~ zRaz|F*rr78G`JZXG*YX~5K@5k>G@0HdlBo-6v1jHye?%qRwO@+-hO7J^4LlPG>@A1#{ zQFl4x7tnG)+cz_2Mq_f*H!U)kgg{iHqxT)Yr3ec@K!`)z_%h1c0Y2Eu(dMPkrhq5v zY+bKWfx|sTiOEB71HuwS*CDzA%ReBv4*7Zy7RM0n6`5#chfOJK`ze)Y6>d6Z?UmyNHH!3DdsP-ARyDo}1HO+>7_um7 zx_gj{+_aU_OUH_~Jd?KI#ICZujD`of2mDpCv_zFGE%6}tfL|j!WGu_i-u>4%{%d{$ X7`zMSfT21V00000NkvXXu0mjfkBx0` literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/time_add.png b/base/resources.pk3dir/gfx/icon16/time_add.png new file mode 100644 index 0000000000000000000000000000000000000000..dcc45cb22d734911a75bd4950e2571a16605a9cf GIT binary patch literal 827 zcmV-B1H}A^P)3?6FD7nDHK>VL42oe(*rZTUs{)lBOewOJrAS)@sgRZy z%F>hyq)^%d($a+jvbEIPma<%g&wCql)nJT?C;2jG&YAhmnKKgsAmV>?EHES~x~T7X zs+sKJY)$uZ$;sXvQYTGaS2d(|cfZX!|5t!kR#0tLbM}|5W7u4C!0-2gAiP*vG{dZu zpszlDTUwr!_ea36B)`&b5W?qi!|L|o{h$lgowKNt&7f6j$CPayE~_4jy2lXZ$7TKo zP_^Rg$&G$-I%;z7v@(FfmgKcnw*_L=0_Lcb zLkC9)hC&cDim*X}0(*PtR1HFFBT(FKf@MOAIxfq_05r`>yFTv5iHukZk`&|+%R~ULN=n0< zwMH{M2Y|s#BDvxd+>Q}6WV3z(I?H054vP{MG80A?2&__JW&z`G!!PDX?YR7GjC`?n{pDbW%Dq)z9LBVBN!qPTXY$6O9kX}RpA#Z z8F+~Dfp{9Q%Y39-UM%Mw{}$%PsxdTSK!IosPpU?dUZKMkZX^^l_4w63ngulA_kS(O zy_Z+Zxe=5L?_x@m59gd1&eSqXN&&j;A0wZRe+P0j{YEgzubTh>002ovPDHLk FV1g6?b$0*& literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/time_delete.png b/base/resources.pk3dir/gfx/icon16/time_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..5bf8313c6fe2d345c2e2e27e163fb9a91f902f40 GIT binary patch literal 853 zcmV-b1FHOqP)LI8ef}kKQAC1Vu3=||mNqz7>Z<*DWS(X}8({x^D&e^=6 z>88%hn5MS5Hq)H$;+)OP=KODSbNf%kRfIoX_w44(Ip*@cSPfat!hc zgGXB)iRGP)^{>KgTHcjKOPiBcMAb>{?eDTK{}mwNv&vMxjBTTO3~S3;*lbo%lm$x* zDyXD92;awUHor;8{UczA$1Ksv%3(Ddpf*_XaX^nU!8A(w-_X#b!Q|Wu^y*P`SH*$D zj7d8H5H%EBk#(lhmQ_6@3KLof_0Sk?u-F_h+cu$Iw4tF_gSKHEW)(f)KE3CxVm-Xz z1N7HrbkCE(_l0%v#X5M+N>P~mv5YNp_sZb`D!Md~Dh=r4rl2AxqQM6ks83ur8K%G$ z&0~hV?A-Cd;dFvs!@(*6+1+jkL<5k_QFz&;#MDGHs zx|ykH-tszZd6}+hsnhA4mbcBhIj@s?`p*w5Dg4rb2i|jDp5J@k!+8k+#Q$jBrm-;b zjI8KseP=m!=5saO(peF1X%Poc*5m}2mc9x+;BA8joZ_!YmwbVsN{z08NoZ6uRAxT} zk99wE9iT=K?;*?=p`#Jtp0>~VF4MrJWP?Gx#eXP*EB#nU_?@Z5Hb6Z;aLJ(mhD4DP zQ;QZDmVaP{%+R8k5WXuzSR@m*vNnW>-SB|th*3=&a_QF=ZGh@5za{pKHCNUK<JI)Ln2%+72(CGdRsrxF>Lf1A|cRp%M0f4O0fg+bJ#7z2L=@OIj}F;-Xd7 zm`%AVJ{q%W_AdV{9O#6cG;jUqG;SpF%DVmZ&DcpJw)}bi3kR9nL}HfOaR2}S07*qo IM6N<$f{5djdH?_b literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/timeline_marker.png b/base/resources.pk3dir/gfx/icon16/timeline_marker.png new file mode 100644 index 0000000000000000000000000000000000000000..a3fbddf88b7661e9ee2a434ad4152cc724db24c5 GIT binary patch literal 327 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-%+>FMGaA|c6o&@rz!QG)Hl=lY!! z1v*=JI|P}v6PV8&74ykGbnHgML`m~0TYQt3?ajRZzjDrI(GNdQ-+es!^5)m?umAh| z_lML2hJx>}8mr}YRTjS1X5c%1=To>j zEp`{T<8b2%3kmpmE&u%$g;f!Ou2+6+ab?{tp`+Eo<@Tn7>)N`e4#yAy(KQ_jApxR2 zTwy>}5{4Z&HZE$4TztEY4eB^wEm!DE&<6VJfqm!9 Wxdqp5p1KL-FnGH9xvXIO@l#-%@K+Q7zAyIUxr7=;KLsPe99&9Qy zmp_aWYb=E&ic)qE1ceaTL3I)s3+v0Pdzpnl)xpCDFYk3f*Ymue2{3J{X-|sELAYmu z=`Mqi(_pe~fr(oVM(R_x-rovW3XC#01TV%_L0BAvr#_hKf!+|yzTW7{?3 zIuq0Vz);x1M>XE7-^4 zB)oZq-|zSSd<|RjL3Q0FaG93$Sb#=w6_iQ0NQ>FM@oa+ksPjrN7+e#)=Jk5tx!vxB zO+TG2$)d_PZTpo~g1ZG9e0&b?=MikQx3}AOy1Ns6Sn&5>og;!Hg4gVJ`{#y+hUEVS z2o4GUBDiwY}B+wa2=)lh*=g2T3C=Dq fF3wcNZJhl8^(M*LyGLEt00000NkvXXu0mjfpmtoM literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/transmit_add.png b/base/resources.pk3dir/gfx/icon16/transmit_add.png new file mode 100644 index 0000000000000000000000000000000000000000..b7fd4e685f6069f24879e9f0e381bc410832a85d GIT binary patch literal 803 zcmV+;1Kj+HP)}axRi;}=4r+) z3SP6qaP>4p4@~rygl|5-8O{?hz+@M^a!I*irXQX=V9WwN`2n1{d0PXGsKiQ-wk!bGP`tWfAL4Wq9pM0Aa!>!&@_k3G$ZH8})ZLKqDf z6r6I4DxE^*iAW72CNsV^(KD;Mdin}N>CT(uX*qP|LT8q|Z-X^{j{38qRO|H;0hg7sWIJD9oKUIFk%LU;cqpfyM$l1 z?95f0L82SLaSPGaO-)V3`Fy@e(bdrq3*|=wlpYMCC;~ciBw*hUjp#1ndnAiVSGTLh znyBi2qswqg;NM=a_ZLkGXGHfC_oATSfR@7jt5+-DyP%Qne&BIFq8kw1V9||Hw=1xN znPK?o!Rd6`4UNgghQ_3y8MPNlHR_f-OQY2Qxq>y>Ai5c{m>p|Bo4`9|@`Bs#UKV({ z+*&YS)}6|eSqn2?Jk*V3kysZ+sv&ehv*oWWC2*6#3g2JC*D0=7p2qdYjO$%J>Qm!Q zr_OtmquIL_w}TG}{70Q^x7&R-o6UE=D4N09R@OfQuPti8*69L!1zr@mb**Qa%46BP h1FE*vy!x&7{{lR##&^9e`^EqO002ovPDHLkV1lG4b!Y$p literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/transmit_blue.png b/base/resources.pk3dir/gfx/icon16/transmit_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..7b1142fc70adfd598ce6eac581421d7e6295f370 GIT binary patch literal 814 zcmV+}1JV46P)^~)@W#UgN8qC(979%Vy9NAeJn`# zSw2!>g&{fNR2$Okoji4(4lt5P$>r&q16P0#(CAS`X1XUkTWj$WH+~m^i1nA!c54U2@ zzUeSE3@r(@mOzU7Ss)3zO6X49?eVdR`>f= zD(&<}w=25V_BpD%QfK~{4*0vpV)<6BAI*U7!YSn(9anIo^h$1Lw4>$RCWGxdm8_qj z8-Z>jbWcRL3)o3FSHo3#4@0T!b!F!4__T7a7X3qJoMEqHkXET~kf2YcP!3qAt)$FI)g zfX4xE%Ve@IB_$;X{~G{!1n^hDt+6w}2Edy|MMdmC0|1`~><4@={vu#`et!O#R4P65 s*8sp^b=iB(8ZE$Cxw*NSsD#+rPu4uZkAluh`2YX_07*qoM6N<$g1stv`v3p{ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/transmit_delete.png b/base/resources.pk3dir/gfx/icon16/transmit_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..3d72be2a385aa6afa5b281c13484cf3d90b31509 GIT binary patch literal 827 zcmV-B1H}A^P)ekg)Uh$P6M7p$3e-P5^%^+?xyvUjfULliT5YM76F4isfFHVDK9*4g2!%XFN6B*Af7DCpQ@vNCUc%g&VBcXI4QMNi;bDnJ*DdLIMWZQy5shaeM7Kb6JE_U+#I?VGid_*n zlNM1Lui=p?icA`X8&)XXx7ksvMbED5nrXDor_Rzx%SEWof?J2=eGDoR`zYBypJKCF zLg2<8C|GS%ME4b)HKViDpD>DU9p3YZu7}E06W0<=qU*t(E?r~mC|Ymi!WzU3a-v@- zqB~5dY}u2g9~wkAh&uz(H3b5J1XWd6h^~p!IJmerNd8I#XO_dwBNDLqt0KC?s8zC< zgZg%jRHW#-1JoYfDDZE;-~Ws9q-~=6j=UJKE;W*~WOTH%QG<$X_cgb(5#6BZhKp{j zzFmRcJomwydw4t^mzuipR7XPO2fsNi)E*bE^<^y317w7XT}MSXT^18L_SpoUEu9Cw zUT;X?koVlaZ@tIY4G*>02)(?^k6H_X!!aX0$up~!Nx!m`z~usKeCmOZ0a|v>At*2< zvVH3;xE#f&qD}ZV8~Ub#R|!0#cXqj4s?+II{pRU}o;L9R^CfRC`Z$vU1ojI&B=C)~ zvz8q*e|)bx00R9ysqk6qU4{YQ7DN9;I8NYxfzSSb{wQT$eplMEkq_1=22M}sZQ3** z#D{5jw-|E91qfUzaKco3QBxM2y0dl0M_pSwzt>^?{0|*1#N18>$qoPj002ovPDHLk FV1iAqe^3Ab literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/transmit_edit.png b/base/resources.pk3dir/gfx/icon16/transmit_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..eb9a3dd593055d8fd4fde39679d2845bfc27f857 GIT binary patch literal 848 zcmV-W1F!svP)k7R5;6p zl3h%jWf+FPgoK2|WJfztW3~|@Mx95@cm$)1#$hld8v!Mv87aty5y)6sfdT;niq)#r zvI=Zz3&F1AXGM^(Rah9KN){MD5xql~|FQAII6~;OxZW!%=>vrfjgR4NrnVY}6 zV89wq|G6H99dOenn=Q~?gG_~v5@^#wrvW@4L%SZnOzXjt9R5#%$6~@OaHycSHXxuz zbR!;2YCaW#O{>{-Bn79NQ<>?kVzluU#>~&93v52fx1R+VZjp)A0XoX|(O&eJ=vIpE z5RU92Y$qz0x}H9S9ME1)$O zT28X%N?~=PWZVDiWtRJEQODZ|%nvegUi*h4y3-6f?w!qbIzn_W;x31#bSKu-xK-z& zg4K!Q?Vvh{`cn?Kzk81#>={fpq@x;Mm{CO6&yd`*Q>Hnx!$eob{w|z59yi%{s(f|) zEJ5E5wr1bPw~)sAl%9nzVo@(>K_9uMh_0W(MzCu`w;Mry3e+d9-25cQu>8I5KAev4 zmpA!+qKH|uX5D9a=C7ksd|*S7+nwQ30ivr?mlTdEA-22X@ncipoDK%nYxw3exV!Kc zYhp5EK5}>V!xy6jT%;x@R4}Pf|Hk{Go5|;idqPjvko{D~WVfEN9ute+WVYtgxIJ3P zk9F}Y)5ez~A3SaGfjCLBvh!;?KR5#G^GsWhkvG=Kg@Cwq(1yx_Yy;v^46G1u2L325a7Vma8=h!7E11fLnJkQeeBl z8-<01ZU0-~cDrA5I-QF)o2_`~MuE%n^78s~a&lh&&jNw10>A#SvxXvYVpdjGf+Xzk awLby|YpCk5}c2Js~YM`9qo4TXYEl}>_8GtDHExt)FXIcM+fLqIzDV7;yNufj-%8896dxBf(rBK;5UT)oM+zt>(+FuO&~Y*I!aB_-5bY^12z~1tpDBqa5h1r2Wl0lEc{9ojPl~QfenCC?-TFN z02VR5X~-XHx5$FE0h8^nMJnVU7z6G={;ELGVwl#>ViVbU6^nM z6`Vwej}b`F@*JLc4=cQ#K>owPJr2c-3LWl^q5NaSdmX%+AiYDFAR-E{(AArvu>!UQ zvDALN)uTxHC{iAxd~Jr!I~ z{X({JY(!&`@}D3Y0@+gdjRTDT)IYm@Z2X~3|HhK?vXkiRLDkRFH+&qa%}L|v5{vTy zi!r?BDMVEe$ZvS%YyjkDXJ zV~l_O2^;Wzf09O_tG_2sqSr&!uY=L3=6NzBC#=FRlkd!L8F+Z#t8)!|WAV()%#bgd zugKDMFzsPFqPX}|f!rKuyrXoJ!E|Iix8XboB`w8j{7$A9B{rVyOPF>n9?002ov JPDHLkV1m^Io}B;y literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/transmit_go.png b/base/resources.pk3dir/gfx/icon16/transmit_go.png new file mode 100644 index 0000000000000000000000000000000000000000..10137e55cada13d8591c84070a0998b4ae2c2bef GIT binary patch literal 842 zcmV-Q1GW5#P)L|NP$Peb4zTfbw6BwM9vp8L_@# ztVP3P(Rf(@g5fJ>`Y%Q;Jiibw5O9WPy)ZQ-<%ZXTFyVmF7I0mdLCr5%95B|VWAw%_ zlil#jC5NqWzZU5VgXPd)1Va~LWeNZzpG- z9($&dj&u!|ggJ7-vfn%(Fw(M#CruiYJ<_p8W3VEEfzoB7TP?aix^sQlGpey2U&f83 z2(BO0P-TibgGTMnjS7#=7Q7vzX9?;W87K;;uV9*cRnVIcJ!j;39&CrFY1$V~z0oKk za4QX}W6X-^zQfl&KbxyiFS>oWFC)4tZO05WA2x`tiX%(9#`RGbtEX}cVg@BqZxqp; z#V1=<^Mfx#M0W;94x(%D`~8VtuXm&98j9?(WOl|t#pV!7*Msw{1g!a@i0&-jc3Dhj zaJzbJDM8&&^qO`H{L|y{{Gc@{;aq!6;IjJ!DK>#i*3OSs7Wq|??SA0y1w?m7bakQ| z7u>GNxd&5sEV=e=WVA=ml?^1L`Wq?iJ48amO6F>}1_NXS+i{cVX31j0{(Ls+ygbjb zgTYs=+n8|?L4uy_jTdRj-0b1&O#LbX6y z3il~0?`2~fuOjXCZq{8=W|xAa-EMav_2vfdJh$MSG}Gm)qhq30Le5|vuO!QvKxDb{ zHoRETFA5OYqpIrnBi1!@`x?Uo@eL~iyXwQ{(mQw3I#xl3V=ocq%G9c2C3Mkc68M0? zAMJK~*}~w>Rl08{yW&|}68c_X-IBLa;5LC1m)eUce_mZ0!s(ohgW1{HA%EWg0w992 U9AQtx`2YX_07*qoM6N<$g6IB+8vpa8B{-MRO+d-q3;Nq=BQ5k|pUEm)WqMHu)e1HsCoBnZl&D2fWC zaQI+^Ypcj~qlqjN+KQ~b2pMEyMH{Ql+1>s2yE7NkMta~2=N!)coZtD~5&$KI!t?Ad z$MG3K5aJfgx?{!872ITuZRI#lqksTdtyb{7RJQ~`I$^U_K{Co%zhNU}Spi{>7Y)dA z2T(yWOq>p(RuxZ;w1ML7gxm{mzWemI`nN(<|yr*`feZQuYV#H)Ari z1=G>vINi|>i=~44z?}aDs8rU})cijABZaAtpP*_$DD;f_AnVU~YcQ}?MFF~@lnxDf zyNq(_WL&)Po|mVtd(wFiQob0&DT1hhg-xfS-QxYqH-fm1@dyFt8i e#x0i4_uw}&{+U-AleQoL0000l0ldN literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/user.png b/base/resources.pk3dir/gfx/icon16/user.png new file mode 100644 index 0000000000000000000000000000000000000000..79f35ccbdad44489dbf07d1bf688c411aa3b612c GIT binary patch literal 741 zcmVz1iyEv%?$mbQ(# zwJpuiQJP8?X_`#S8b+U_G6=ziYB!xPAcq{)ZJ0bECH@ zYx#`n8^Wzn^J!4>=q^bltNO15ry?0ecSLkjpT@vlid!jk)Fjf7&)q_V5zGs#3N%6* zbW~7Hg=&P0&~Y(|g>$hC9FL?;ttzPDZbpZu9OLb33^e2;FNTGJxScp1&q4M+y2ntQ z?C(=hpU$3~`Thx0eHwi0x`q+!d5k@|0_WHe%sG3e-s^MM`xM-ig!VcIA7H}X1ot~L zg=MLB4w-Q;Bi!!u2|I+Qb;0{{4Q53YX6+4_aXena{nmt*!YG7ua~`qc>o=?@U?rOU znS7%>klzi*muXnbM6i@4FR@s^8vTjDgy&%J?w?`u>NYMDFa_2%0SQ(qJE<3=<8Bzo zfdU60e*y(^$RF%r$kl)p7=7tlCDa$+J7w>}DU(O#~fk>pYuRvHi1E9^msg{tLeV XM&GIRvfA7%00000NkvXXu0mjf&%8>| literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/user_add.png b/base/resources.pk3dir/gfx/icon16/user_add.png new file mode 100644 index 0000000000000000000000000000000000000000..deae99bcff9815d8530a920e754d743700ddd5fb GIT binary patch literal 746 zcmVR5;6} zkbg*1Q547RkCGx=+ZrJV#zL@SQK$qJV#CSW)Px1IG~1R7@Ce7&_JfOHMV?!rlp(uU_DLu%oT329{ zvd}^m>Zu}~l!lF)$vj*+!9ivWYi3=6E`B>+7|Su$tH+R~2!#ne6eorwU&M#{7<<90 zO$iMuFlR;n2z>v9nKwp!?XQQ|aSfBtZ^J)10wQ zP}rH=KSJQ4N-!Ms3A?4X%~8iSR-zylzlSXd_?|M%f3%_Vax4V#xlec^^VT&5JP8rX z6}RO@h&}Lqo`s_<751_e20DK|@e2`2FToK$y2KTlwyhFyPdYY*B{>w4$%B}fnn&9d zQ0xQp-T@b00q1)Ft+NxwMg`RMry#!}42Vk(RW1t-$ePmK0V@&mp4&IBO>%w~~-qNFem8*NKi5C3*h;eH{=}2kRqEdNlF-|c6B{jNg1xE|{xZ_qq=T?P)vCi#|P&Xm-dkucwL z3)87{8iWe96huvPHfK`KOdC2Z({T6vJ9pwDx$D4>d(Pqff6w7Lmj{5i6;ZyPPpPN; zroaW=6d#@oL2Fa53F~$Su10(RG%K0p3VTuP3?Z=nBA8z$uq+XLUL^QrC74`bU|!e| zr>hK{)%Q!vdmIO5Z3JIvaOyjOX`X@c8-ua03`Q&)f&%p*{(A$q`ZTTjk%q_T7>v^J zu!R-a9fFLScYlKkNBP_Cob=9m9JLVoC-?c{)eOtMnh7qNN{ejy2sM{pS^mgFHJm@(buuM4>=<5Vr$&Kzw{B?uPr; z(1Yf=#g)zADkWnx=MR%ykl| z3Ui42k+O2{bCn)01-s5Sxp|z{G2di&KT(_M6;$EI zDL57JFf}cw4bP1P$pgTRKH$0@h|~aA>j`qZ2*kU5t2EVD5#~@VNhqx{vz8ethDD-=+1vnemftUBA zF;N!Q%PBB5B=KLB#QO(CHe?;R+-C8M?ppDW>R$5`cCPq@YpusFRTaH1i9Kv;l<>I( Ze*oTy+;kdDB`N>_002ovPDHLkV1l3CM+g7_ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/user_delete.png b/base/resources.pk3dir/gfx/icon16/user_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..acbb5630e51a12a1cd30ea799d659b309e7041cd GIT binary patch literal 767 zcmV!wMF|0iq|AK>&MHw6~-ksQ9RtH+=$?!G=zinz|BNIO*d}XYdmm2K>Qw%i9j?X9SgRBJn4W5%uAclWG_T7f?M4s9q5$`w5b| z31S}-Tq~-?NahjDw3mU5cfqF5z)+g+pPplGDyLv1f8WAnTQ+Xiw;{fhcBLH^j|gI# z2~IT;7{m9#PQ$2>16f?4#0x*vLFksSJ~;)W1wO>uQ-rAG1{C+&5Zw%%))Pc(2_k9< z`smoi)Pkk!SK)SAcOy>0d#x(Rl;b_GP?XFE#P>r%M^9Kn>j@#I>kHsrS$qYvKE>lwZZUsXcw4nFNHZZ~?%71a&2u7&aV|47ZvJKBUVO{)!ekB`ACp}1 xSnjsa#jtYM{A~v!cV^R$X2;lcpKyd7^}lwPp>~q=QF{OY002ovPDHLkV1lJ{Vb%Zu literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/user_edit.png b/base/resources.pk3dir/gfx/icon16/user_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..c1974cda745278a404b9e29fa91e0503a84accb1 GIT binary patch literal 833 zcmV-H1HSx;P)wKwNApj*j?`*x8fjj}+T^cdNV;=~VOf{An4CI`(Q%x}`$a=uBQ`IcOG~+O zhFmpv$jQAVt#pVn<-FwXyxzC#)@;^BTYr4EXV3Qe?Ah}?KRp0?|HEG!QT7K}`6R>T z0?GlfNd&N5h)SxRamGIduGtwfO1+4h$^b)DXu0o8M7BEtF^>B+6kDUTT?1tl0&27( zTPtN#enUj2hcV)v4ROVeu()d=+i@S-%91h3XQQ_&2GLH&h;==J>*q}oafY~7o8YOx zW1up~WKKQv35z{tnCiF(G50p)FLR-gi@=FATO4h+zckVifX~k}G4#+4;u7niZGj@H zRkx!55oQOPpc>+6Y1FM1A`bW&7GI~k7+8?J0DewkUh)LOJkrdTe3;U(*Zgc$Er)&@ zD+5(f%bInl-ZwzNw#9d8%I4~~7EHgs3zhUKHpaRkt%*?UWMg-Zz7eUOc8t^s*~Buq zNnU77^3>6u=K_U{g-umARHHXA*H6dCx-dv81Ap`v`JB`FJi0MFsY3lE z5Gw;{eLz-+019a$Hq}BXzXU@)LB-NA6Y>hD8BxCLDcvPn`&N6q`mxc}yMb~sKo@Ed zDbOI5^9}?Dhz0FQMoKPVwk00IILo!IfS6^eQMBJdKtv5PI+Tbj;^0Fo6JmY=Cj0!M zlv6P`lmJPo4+6tWG2fYveukB1DzkD{lX z41Nw7E`C*@hclIfDYh$GCw<#Tk~h)}QkWS=$Gv&wY2h|l6&7Q)uMmBi&Zxg?1_yGk z;>5+4_M6eEhsL=ygB_>Q-+`#k4z^f-l|x?d%y)UiW7wGPG|s;O<^@R5;6} zlU-<1VHn33^g%H_Q)k_G9ovjfnFiK+H+Wv4;+`mU!eP_1WYT1cBMG4+b^?L6?AK< zB&!jFQPqM`i@@k4u(!!^rBRBL3hHN70i&#iOH+^0u48x?v*GiYACKJzT+r-=qk+oz zUpus;svxs4gSf1jroEXH?t1wdY3Aof0-iGMy6$K8JD3_XyAT<+1dUmit6yK(! zNF_M9n(Bm#E9}vQx7n3q{&nCY)~18Vynj^W_e>bi@1BCANxml61a_7c$XmJMZk?*# z;GcZLxX)MuKlTCU=6xU;ncBCjL?Amju!Wp&&M@$uZ9p#m5yGvf5Ue8*EJF}(aLDzJ zAlPvPBtx=PWAE0I3CKlubR6lS2?)Vw;GM(ZEgZ6)VF+v#S+fswc_vu$Vh-L#8KE%#xl>f)!T)$#yRmO>TTOvB+HZ zV8!UbBF$h)Z%6VHiyt@rn*}fK8xy1uKWEQR=pEqAk+P7{#x6 x&>pVMG)#i!=x;v%@<9vjT^KNkD*ncQ;SaYr!-X7+DklH{002ovPDHLkV1noBEY$!2 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/user_go.png b/base/resources.pk3dir/gfx/icon16/user_go.png new file mode 100644 index 0000000000000000000000000000000000000000..0468cf08f3760dc13e44aed69f4f15cedc93b503 GIT binary patch literal 793 zcmV+!1LpjRP)a8r-1c`3+>owstQ*9I-_ekzW(ohmYMY`{P6ZeF5{f*M765oC3mgQisOM;QQbX@ggAS2KgDM2gcqZA9XdZ>iF!~Vl<60PAsYul3 zdO@$k{dkx0EmyGNDt9}0CpW25-SK_A4lC2`W(<=`JkE57@PX&*6@@GQDqw`DDAt^o zq{Ey(Out`(COaJJ>@YJM^^2KrxFq*RzAhRU<&M8e2tg%w*9#|$0B%$xx&b3n#4 zkf!uOYO^O28&82>e-b(E7tlIZg-q>P1XbD?eadJSW`T2LeMI1S3A7{YkWT@r!zKv( zO-N}zjVBW|c%-j32i0RzNc%F;I4prs$%aP>#pqIKVL?pfIIhp@vQS;GLtGb-&KrG^L94A_pU%f6M3**AM

    gJ6i>thi*In%G< z11qR?nZ<5fV+Cs0?EF;*rjKIYInQ$Ka$^8kIXfoF@SaV-aWlw~zZ}ip35JN+^=tnJ XxNVQ!&Csrn00000NkvXXu0mjfj)-I{ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/user_gray.png b/base/resources.pk3dir/gfx/icon16/user_gray.png new file mode 100644 index 0000000000000000000000000000000000000000..8fd539e9cb04111e950ac9b0cce82676f12f67d4 GIT binary patch literal 706 zcmV;z0zLhSP)%zf?XuhjnHwp)vDVV-Nit=+l<1e_j@md!Ei+v5AT8J`SE{vdFuew{g2kYyx=h3 z4xieMNJl*eP72^_-v!pJyZ=`JAM1)mw9ObhdlWZSJ22`#g1!y`+|mPJoz{^J0U@Ip zqqZgtkkAd&ArfvtoH-0%$6gp(_f$3noIl=(%W5IUuV^sBo`C&WBd!{oVQoJMrfnxi z`p#^x2^duFTU~s97sdAz`2P9<<{$Or>$7WEm>ok@v;XI(hZnch1SA}-?@Du%ST1C- z@^Ol2n(j;UQ@G<16>3&!ll!(xrPAzppcCc7J*<9tO11JKgUNwTh{fV3qSNQLtqV{p zl?^JDic_oANTpKf>FL455JRQWXy~0zr{ni=;uWj`kl?0ZFnEhM@}^`m39HqLY&MHb zCIgengyG>~csw3-cXwB0GT9)3Y_0-G@Dj_iNT<^<7z{8Pjj-G8$mMd#=ku^wEYNDT zu-R;gMx$`M-4(f9-d6=I3^o5=o*hIu90td6)Z}nDKqjN(GYkW-*9(`+1;5{qVlIle z{VnAxU@_8CDZRK(4T(g8f=DH5<}3B~_974nARdoX*pHVS=7PdX74Z47KQtd|`sH*w zq1WrFkyk7hqy71*_%rE`uC6XDL`7wi;nuvu(zLIhbZjEe_=@yhBIB183I%xaA+i=F o63H90*)04vGrr7ApigX07*qoM6N<$f`O4mr~m)} literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/user_green.png b/base/resources.pk3dir/gfx/icon16/user_green.png new file mode 100644 index 0000000000000000000000000000000000000000..30383c2de517fd22945a87b0528d2821ec4d49ce GIT binary patch literal 722 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 XHe4|Dt4X literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/vcard_add.png b/base/resources.pk3dir/gfx/icon16/vcard_add.png new file mode 100644 index 0000000000000000000000000000000000000000..2a68453811f26444e2d04da5713c9c757dc999c0 GIT binary patch literal 661 zcmV;G0&4wR5;6} zlgmp~VHCiBGxv_KMl&C2qkCXb}Wq zf!ZRmAV?dcl3`5C9`u^&j*R%u>z&8;KPY{YWGtbfuK$a=ExUB}iH8 zEPs4~N^jt-Zswr3g){Ci_UZ~2!Wmr0Ma#WbhXyeU7+*w?FH!AkTK)!xHA(%V`3nWCtofZB~;xy1Wp zclf$8!*6>HJGqJf=sC(o!*&OC`_`CUEJs$9bD*XGd(Ea)E&#^XnS(ZgInMBG4q?C+}4skYc8sQWiIn=|m_d^&hoje?QvJHqv zqa+duDl02#Y;2^Yq$CGiSe?h^a1&_01i;l(w|V?-kc=Ef7eagphr`W62s%1C9HCH1 z#bU9%U$?rx%&ZwAVonn5xl8}}1&XvnG^ef{ySYZA*K@tzyT7lq^#o0|ZG4^&6PlhR v_HFfsW4GsQ^m_V%%Rnix4h+5;FoS;pMlVc!y2FYE00000NkvXXu0mjf;fN;k literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/vcard_delete.png b/base/resources.pk3dir/gfx/icon16/vcard_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..b194b971b398c3d81cdb3daefe3fc4c5ba959eaa GIT binary patch literal 651 zcmV;60(AX}P)#u+p-Y`QM29X# z5S}9c5Y@7+BwJFTy>-o9T}AP^yYJ2Wb+BDs>L55U%nZzY=R3oUp|$2H;^T;NWB|3Y zvN8%>1@Jr%tu>zKRj7#kWB=+iBb`pWEiEl3z`=c#{QudKpGYJ`X|2twswy7FgrdF8 z#`pJVX9r(v568pj8EW`JBobkCauYjW#NI7p=N(?$j36SWI@q=E+auicCzdRW#jK4U zn*+dc940Q+;(68Ou>eE_RSE!{whLVB?clOsG4uH=3DYbmPEAc!EN^gda1TI4_KIDP zkC~GwwLwEu6S3j|xm+F^_5h;MXt{fdbp?Y>Yk}7ASzf9>a=(hy1pTz{ESD4GPbToi zUn8p)5(v_D?Jm;XyU(DbevA3_0A4V_u{J;Xtvroh7N{lr_9?AvF}iMyP#r$U?%X8F zndca7OBl&yQg?TESIlSIHibf=OnLrJl!5Cb)c$-2%hS*tU`?GN_F-Y4fn`}_G8sal z5S^W!)Ya9M0cF*qracTp_x3Mv`~+%q9VH^kcs$-CBJ}t78?&>sI+aRQUSD$%`^y{Z zU)`p#`x_hB-ZF6;1FmtHZ=4?P822~UkDUs+O8HW3XI&OoO>y%2zH!)ho*6zpx|2)a lGQ~I}re4d+k;eSjU9UZ+4 z90QP2;y4ac$|Wv@_#^)I2TCfH$_D}g6<{%&x%_W&E|0}xLUSBPb-Uf%j0$Yy8`JSu zIJqCV%4?_y)^fz#Pbd`P^79OaX=7w<3^T{$(;h0T?8^6sNPyezP`j= zwjWIh@oP9Qd7EC1rcL85DIsd_W@^d=?=OJ*&@}nP1cmEP;0x{~GgM8_i-!vgGKoIQ zgH=4y>X`a$v%;^l>PHd)EBy@BisRqBhpB-cbj7B)WEI}h$^`~%ie~AWEJgZDDXY{m zXHAOb1ZuV$&E1Qy>LAwWBXp0#$cJ8}qm%SCE&!ZA+%SI&!!WQc3u`h#f!T>~QwwJD z4lX^9+q;1x=L>;DHyCK|#x)0!NF<0xqYMuZlQ-P2qCDiuU8_Gh+~hpQQ;Y9Yg04!_ZE%SemW!igKchx4WJa+_9IUqH2;IpT3(}`$+Aj z_Rhbl@sAabH~F)5Rh8PVnjntbie%Fhr;c9#IQTC){{(bKa?t*>JG%e?002ovPDHLk FV1hfYVB7!z literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/vector.png b/base/resources.pk3dir/gfx/icon16/vector.png new file mode 100644 index 0000000000000000000000000000000000000000..a1291c2dfad75b289f88ab762a3a32ccb436c1ed GIT binary patch literal 481 zcmV<70UrK|P)SXcnW4?r|Fc?Kd3cm$;%kZi#G`Sa_VnwmC}YZ26Y zhXbnt^XAQKXm4+SUQ}H6r(?sz`|0x@O--EjU}EI72kk(5e$=!F(*t|%| zOO`#}*s$)|C0u^?YPrGY(Rf4Gt^S&sOU+enjCclWzS^+v`E5dh=Tv=F*rDQzDn?3c zT=(o=$L8ms2^j#wwxyStFa(R1K0Y&H$BX|!zZw%`2!=rX%m*7M?R@p$v*kt(Sq6Bw z+-#h<SXcnW4?r|Fc?Kd3cm$;%kZi#G`Sa_VnwmC}YZ26Y zhXbnt^XAQKXm4+SUQ}H6r(?sz`|0x@O--EjU}EI72kk(5e$=!F(*t|%| zOO`#}*s$)|C0u^?YPrGY(Rf4Gt^S&sOU+enjCclWzS^+v`E7KK`BNfm@}@+5O6&9g zAKBvY$)m!m&7tCoDn?3cT=(o=$L8msku_)Z2R1aWPW->+%GCcCp6&YIzdP%Hc)#v{ z^K7YJ3?~*XeSBuZju-!del>=P#kRYA-*|b#|Bcrs{Re@bJ*ofu_oM?2ko=BeK>W-H z8z=32_20AQMh;BOr`quUwkvb~BZEzsrh*K>3?%QCn~f89y!;>7dus_y%rZy%d-txS z|LwaHz?$24Cg64fFlxNpH$DHKxA@UB$BHX#ATglAmf#+Z|Gm3Xz&3+u5FaSsgJA$L zYJ@6RJ^fR$>hXWu(o2CbaiHQ3ApQh$Hk9rFi30!(_NEBmXg+EH00000)+jEP)SXcnW4?r|Fc?Kd3cm$;%kZi#G`Sa_VnwmC}YZ26Y zhXbnt^XAQKXm4+SUQ}H6r(?sz`|0x@O--EjU}EI72kk(5e$=!F(*t|%| zOO`#}*s$)|C0u^?YPrGY(Rf4Gt^S&sOU+enjCclWzS^+v`E7KKMKBsqYa+IO%4@TR54OoCBdg;l!e)kIzil@!~(wuf{O3oi5CGzX3J>pXB@hf4SiQ|80u@Uw1kD2a4arFd%;B zgN>7RzWVRkaw7*O26Fblv+MpNgZK3k|3Tsy26(sJY@E2`<^RCmTT9?BaAkh{Wp48S z|3FPY${7B?1LB7n%>RMnPcRGsMvZs-rsx0j7C(CCSaF37Bz8Dls^Mgc>hEXeivM3# zvi`rD!uWr$FUy}DuFO>!1^}Z*sB+cQKNYJU|F(9002ovPDHLkV1gG5LN)*Z literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/wand.png b/base/resources.pk3dir/gfx/icon16/wand.png new file mode 100644 index 0000000000000000000000000000000000000000..44ccbf812879c42cb1f9587d865bcfc337ce6361 GIT binary patch literal 570 zcmV-A0>%A_P)hUn2-Navsqo?5A8 zh}}V^=%7@_%C;=H{tGpIj5CMu*>5J=i;m^t2QTySd)}9aAppozC}++wDz`eOViU-dbRRoz=JsVlZk>N%^azhi%=xTCt9`LQjtqNFW~e|R=r9= z`@I3J^#z@aD5yBuq2DLQO#|4uFW6R5kzPZ+h&6Af&5}POarL&lA~3t5R1i7uh*ffDw@qEs=HBW ze?CI~MkvG6H-MF7r{Yv4kw_q&PNP^XqFgTHXlH@RpLO}3aV{T{Ez=8lo;PHV$Ads1 zfOtF(s5%5V>3qE|&{lueV1Y1j%GF zXt&#NI-LlGLPN>_18TJzN~Mxf*f6pY5Dteo^|P&3>(H{!KTr&_wGRQWb^rhX07*qo IM6N<$g7V1&P5=M^ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/weather_clouds.png b/base/resources.pk3dir/gfx/icon16/weather_clouds.png new file mode 100644 index 0000000000000000000000000000000000000000..3f73eaa1445abf43c729c134b24e3a308b61a6a4 GIT binary patch literal 581 zcmV-L0=oT)P)51y3fE zx%w@DD2lfa4>~OCGd7Nm`OJhY_mM~>Zhr}oW%;_>?Rs0S*4L#qhyF>!#}6{}`ym$d z3Buv0; zoaA!3@5yAc6buI6aLmp%8cvFa6)*`v ziL2Gh4c=@vXTXaSngz8JkH?=c0QGwP-E1~<4=IuM)DpQMAbqXrbn2ezx(?O?e*s`O z?^U&04K$n0HG?_ja+xm{i>-7zeF}v_$5<>TF=>%V>`OVZD3%CgcZ}Xt#Wg= zUCanah`Li2Ew%ac_+ze_E?0efU+V~mRRp_uc%SF+e!k!Da}GxaK(>>T4DI=W17hEb zu#d!kJhZ_Kg#K8IP*XU*AP=RXAqbZ8^O3bd!-`Yik7OY#iXX4v$>~@UAY_yh#iTjP;@L2+%MCJ7r@Gr-(5aIBgd$2Y2*5kXT|8YNXTYnvze#aoh;qkzSx~sZp6HHb!| z&}cLsiGbhl-|zK$N8D~V?{qqO^0GX3yWMNGTC--eIcqc;1A4taq}6JhYPH&TkcSOXkRtuF%1?6%Xf*>H5%fVnUI3xklXq2s1tLXK5Xt&#_*Xt-03dra4NTpIp zBoZhVi_q)!r#hXE(`vOVbAUh~(Cl`*sMTt7LeUvSID)|-#MY3>WDtwRpwVc!Ie<8< zrg&z(600PURQ)9u2MUhk;C8!_&1RuitH*Nyr_;$2A?cMslF8((I&qRtry*_y;(TVV z2u!6?%{#DKt;=S!nYGz$c4g1-OHe=x}~H^(oS?qTl%zP(Xk+PIAm zi7Sv2N&-eHdh2kohT|P}R-N2O+Yj-6<1!Wk_Mg+|M4OL3ZP3__(-;ePXX44`y@g`Q zuS{Zxzck!`eFt0X)OZk~m@@;0Jau6^O0Dj`x`B6LDzZo@2@tEP-iD~7eo&@5i}b1=~CRSYnKceL_LH+CwnM`4yJ49kFhue97LB6 z_K?9#hng$~K`Gt*7nH_0PE<*@PCxEP->Gh}a5DvZ@bOOX?)&t;cXtx!9NlEZ&<)3} z>lQkl&f_2mb^%X(-$#JYfKT;${d9hx^sf@y?Y1DlD;A5}>2w+qLeO|TM!K$l1CbYv zM&oqBLATpo1JXWV2e4Wym2M}KNn}}8C?MwLa(TPo@9)C)MFCLW&*$^6Gnovclp@db zkYN~TW>xO?6B;iCv@h#RTlL^Y@a$^28a*VLCJsb}IoNX+I9LEWT6h#Ta7(sb zMx&7sIEnNC1daxSL0HPn%~ya7cr+{FJ3s+E1e`!)4;PNHrk%Zs$w*-oVG&)AW5$^> z@i``hDW1zPC0ucA^76~UCXSTw{P^d}Rz6X61K!$PO;j&z(%QHiubvx0>%pCP_1A^p zDnQ=6^bY=#BM#~x&)yTtWjA2dCtSuJqcmVp0;9xdasUzfD7y}QrGMDMk+-mS^yA+8 za$G&Ph*nr$QVk=}3M)&hc^PQ;*Al8_5^a4Wr2_fwJo(zI{9j+=Zxg9)Ryp#|fB*mh M07*qoM6N<$f`IP5ud|Np1|AOBzfzx2!k2P6f@r4BdjzqS>RTgk>`sn)j`siZP2nD{M|4%RQ;YX*@ nOhCtIA&IFQT>*yuM8zfmxfCmlqf70K00000NkvXXu0mjfD8iim literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/weather_sun.png b/base/resources.pk3dir/gfx/icon16/weather_sun.png new file mode 100644 index 0000000000000000000000000000000000000000..0156c266e4e1fbcd1263fab2c2dd1f3712553d14 GIT binary patch literal 623 zcmV-#0+9WQP)Wtv3@TMo36t?!us(ut2(qE`#u;Y2=pT zq@2~2T~yXyeA(Qqy5;+9o4@n>4e8r+MnSPzjxHXahjaKm&-eRqP6dF9|A~@^;+?rt z=H0jE_T4vTwd@82LFU{PN7lpd$oktP$3Gho==lu{2>(S8IKK0m@1#{_mk%-f(Z z+<+0WLyL4{ZOnvyEl7}LBImWjh~I^nZG{LlL-;RKT!Im`W9MTdQZ5xqr;6nfwX(

    &09}?3!+0xOT@w2!VY%$ zj|Qoisx?Xewm&q%SbjiFY^0(I!gmV#q77T0t|0EJMfe#*$tA9gs83{GdZFA;x{o96 zB^%K$7%@AxKer&}ti|FWs}2pYzTg0Ry6;OQZ&K!w#ON`Q%*5Js144tWhd>1Tnd7f7 zk-!t=?~tr%T0tsJ(--<#x2)&;s)i5r7k+}jpgM|^Wqqb{;s;8N-ZpQB0Ez$r002ov JPDHLkV1fyHAhiGh literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/webcam.png b/base/resources.pk3dir/gfx/icon16/webcam.png new file mode 100644 index 0000000000000000000000000000000000000000..af71c30610862c76f07e948d8c28433c7d338f9a GIT binary patch literal 728 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 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/world_add.png b/base/resources.pk3dir/gfx/icon16/world_add.png new file mode 100644 index 0000000000000000000000000000000000000000..6d0d7f74c0d89a5d1975eb65c3e048ace0290daf GIT binary patch literal 940 zcmV;d15^BoP)%?%c;Y_xOF9QVIY7fRV}JLEt>l17rXb zC;_)rpe}tj`1Q{K005d&3V@NxVG|ey-h3^0CX$Y2uaOh_TG3L)SA z^5q{Y0Gd*Yk;&l@aHG5N$^I8}&tW+cTs)R7jj)QaYX>Od5yNKFonUrjc24->neX1Z zQqlo{(Nhh_`Ujf3DM$}r*APOdD#F-=DYy}~ofvDS5RWFFraSw1hv)j=0~p1#4+emb z-#PZGF)#Poq)IgqRGb6_H-zOte!Wa-f1gNt7p*Q&Ut=5B7iU_(xixy%=p8=!>AB|K z6PgiYQx~9`I4Bd`-ZH2}_By5ADbi^dQ@DgQMMO6+E7$01>qP33 z&Vy%>nonQ*X>`xY>R-KbdE9gTpT-w&@@z{Nbw&;8L_l3wQX6(ihFpr3Ekas?*N>kE z;DZ;w;BZq1Ku8DhUH{!*^LOU{T=|Q0Z9TN6Ob)~qjYgRU-KJPBvam75g{wmVTo@nX z-u4`Tqba2Tcl#FWG)4l2eAPSU$OVbxOKKviB!WMq6%|BL%)*6IvUcN65jTSPSg8@k z+Knw0t;7~vY{ZsSl2SuT(wNjF)5&CJGIx?Y_woPtcT-F8EDwi|v-vco6!&IyVq_3F z4jcel028PJmsOxX{b=yZpYPpk{{coPMoeG~c>d|!P$U~`!Ll2$JrL4CP~d$2tdK(f zB7}VL^C!RCybBne7zqKt_BQY8Kbkv?87OV4qzxtsGdSGIqBd2HI~8`<~a zaC_fw&4`iL1*lf;lL@XC4C;=~%*rM~v_fRt4cycm#h`*&k?d~D=~owL8%^LqF4e)5 zy-G2v^RV#%0fMD9567vKZc|u|GlquGnJ&O>whNqkRaOr?~jDezniMGiA0Is1o?7E6$y z7w9TQdrO^UZ4hh4$6*rR`x}%(2%(u$1ZB&!I+~0O$><|27fl>LL^v8D+8X2LLJ8+e zhQY#Vj^=+Lw*C)WsTidVi4;NA6u$U#v3#pzM?A;5+Y@BsI|v&&e8)x^8N!Jy2NzFq zEHueOuf0X2YZvuvLua}r|9ZzWT3E~(Z4u$a@=$MpT=h{@>oX?X`_K`A|M@>q{0r#kV|&6 zK(wt3j-P?|%kcIB=GH86Up1QmzU#koVQ%V@Tle-3?>oeeH4~$%5LyjC(6LjE*i%2! zaOO?i`fY5WW*JC>)w?o1@yX*!;fs^Pmq%Xhf89j3p;R1A*T_wuAT@oF&PE?oU#3}1)g%qIqTsXPaq-^2FjA^a Tq%@q400000NkvXXu0mjf^C!N( literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/world_edit.png b/base/resources.pk3dir/gfx/icon16/world_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..00794d4088a00c6baf0c26268ce127cc2c0277a8 GIT binary patch literal 945 zcmV;i15W&jP)wbexvw|;D@Bpf2#?5tPj)lD7w%noq+*50?iyU*w6AgL1SN!I(xtJI>ioRNhm3 z8y=*@c8$zNJK5S0C$-Jo_k6|Ll7+?aK9-_;S@0|HYf>1rjrX%u;FB{MepKXNWhx3c)tdmO*|ZNArkPMxVZ889e0pvz1Z#dze2>G{HV zh$91qls28kbG1mEJG7MiMzhUrQU&Dok7h|F~{5T*SG)I#1Af~Z4$+Bm-QZ|{agwxOcT_6 zh)MA>qt$8jm2IcNd=z7-0Y$4cDTf3vJ@HICtF~=Qxv<4hB7Kb&OBE~D3aq8uXgl}{ z-NV&r%qNoKYI3vS#s7WdzhrEE;bGanS0DGEO{4DI*0mjq%?Tm=CKwQ8KRy394wBI; Te6@B!00000NkvXXu0mjfI-kC4 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/world_go.png b/base/resources.pk3dir/gfx/icon16/world_go.png new file mode 100644 index 0000000000000000000000000000000000000000..aee9c97f8232fd21bdd23804c83eb721ff597a96 GIT binary patch literal 944 zcmV;h15f;kP)Vt{;GNX|PV@wQxfRAQ-FeWBO z_okAVsCzMc+6+1!88|n0#f5DY;>y+0w55ffp3Cpz=VNHC0RRA)nx7m4J_e2fEr1D> zf$Li7b6<{q_X_|3fT6VpU}}ES1g3#EU(cKfCPFP#tOhI>gtQSn;qulcA%*-^2>JFm zr+(T4FtpZ8%})k^KL(S1BPTO2QL%$KxGYx;>U5BTrO?79gvFL~m7AM47lbE{|M1p@ zvJU{5KHA(pGTJssQM!0O10j6WL>(4&6rCX3c8K+IfcD4>45pqv>^k0$0RGbW>L~Ep z>F(G3_hpqWYSffq&yG-Z0#t0sZtPO7RtY8w81XE_$%9;8ywUmn_33;5p~)j(OtcLh zGW;R7d;;`7T4jV=PyEzuAB!7%sQMDYjz>7LEO}MJEJ+SEXMDFFKWs9AW0_c*yVfT8 zdLO<111JQ!Z5P|F5l?92}SW-(dg4!8-@ngsi3V^Oiyy@FAt+W#MZLO z+G>n8Cxq}c`;$Ecm+#=&HP9L%gkegdiWRq#ZuU14t$&X7yov1vXjLB(4@;a4kKLRg z-PA=-YKUFC%EJ2Z6sr?Rp~|N4#O=q$)pS=l!*Bo1(-`ie&YwXjm+`*$kXj*?M4{O% zuhGAMggv*$Cl@{hx*zyFSA6yJ!&%W0X~DEMC>Q=Dk#Mkui`0r-AY6 ziYp9c#&{<6JiCE=qrPunJwM|*-o=^4Szb&J5cfBbh$w7fBc$M|SUag$2d(i=0{##! z(KNT$=DD_V!?IjrCV=O7?_9~=opWmL;fW*1d9-cvk8qg2_BpO{v4zWlWG};=C;2-! z$Cag7CoJ20md|EuhSnN@SH6BZDm-yscyj#Rk@rnx3a!H!K7(Yu!lxHc)7Lu8)up-J z2HoDfaAs*8z|dL)001y@X6Owm(^b;|pVbz=yzjpaJj$ zhrpuriKefui_0DvN;1Ymq&%nwWg*IrK!Xz^eJWuq3u2H~0ra?EC@ge%+`A>6mV z9{TYo{=G6 zt@5m|4G+Q2zKv;Ch@O;`PfWArmB5n3gvMsxV&Iu>97{a!2kL74wd@!f_AP^O%_&ND zm}1c*+F;TcH^{p$P_|akvD5o7vmT>HCkP;z;;&+8tDBI;koi9eX`W!oH4`pYaHlFZwV;$>vvfQTw zM-`m&R_SPIBa^FUasC0GCCh%{h`$~db`z&-lFX#%(f>H6JD6Z(sIW`RKE+xOL+?+uQ%q z){?+F%=6pqEH{6=NzusC-*<`PZYiLCGyKD}Z8^V8ul-K=AV@SE1t4~D2*b1(9UUc= zN-;Dv#Ngl{rd7e$ZUPXC##BFmV>$26ZQi?6Po#@{4gllsPbku3Vq${Y+FAf~T}OJb zGWEz9{(zcvI&CUaN&p7GcqMG4&7ULx##68M4k(F4l7Q+Xm&>uSv4N&(w6?a=)YOC{ zoYLN-J?7@-9xGBx007$C+kK7w_2Z$(k&l}jo2#`dO;J#Ipsbc$pS#^Dy3Q&nSeE5x fGMT)t>sS8=`naU3reLNz00000NkvXXu0mjf)bGN+ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/wrench.png b/base/resources.pk3dir/gfx/icon16/wrench.png new file mode 100644 index 0000000000000000000000000000000000000000..5c8213fef5ab969f03189d4367e32e597e38bd7f GIT binary patch literal 610 zcmV-o0-gPdP)^jb z4`0v}DG1te)wmeb(>p90leRz?_mO+^JKy=v&2<29Od6?F%9%(c8los#f*@G`-%W&* z$)uBj2i@u-@SgX}gtyWPe6d*|w6h%R? zScK2#Yn%$sum0cy>90DmY*i{1XqpClEtktsRTZ)lCUe z<FogV^*tm>8*AlX za4oiR!&85LrobG57qUHUX#{>Vz(RHpB5|@>9O6N$jqB8>%($0wxE5R3)b>Y~xtCo$ zCgEk&A?_#IxHdN)9tqre^o{ho4{?hmPuf@^@I3-wncaRd%|~O3xbrKY=&TiwPYkJroM{;WUQTuMY8vpg}f4o)2%U3C;eEDoiEh?94d(rV57VIF#8VqzW$HrDC|#U`x@QDbgi zVl)t9GGz&YY#D?gc%>hISA+_EBpnXt#pnC`p6@xw0$8TCbULjhlgVx(kuc)%xbgqq zR5+DNDFRN0!y)7Gm}oT0i39}h4h928qY?Rho^UvPGJ#kuW|-Amtrn`Pmd&+bFo@sp z$LI4IQw7BG?|#2ewOS<<3VjL$0=lMY^m;wqZujv5kx1l%Sl;V&Iy4#$ip3&@LV2!7vhhN=PCz%^9v24`qb(+m4W?!q-&~=?ssf5GfnAmJKV;3bvpDm0(NhahZ=&^sqo6Odj6>)Dq_3p~4~ zvb`d3Mydwjt&Df^hVmLtI2x=U&h9(JVYX-!y~z3zi;1>=LY;o(bL$(Yf$lf)dMf0-u^0HrpTG Wk@)HE*94aU0000bIQ51&Z_netrMv_Rp78XH7kbsJXXkj5}*6(u}EhTgM}6% zXkjYBJE8$&k~wo`@3r>&j3NkPH_uZ^ViYwasu@xD+Wi&rA0B~OklZnY)C53B^)gIkMV>GH?=z$pP9!b^~gFb~W{_8@s7 zn@ApH3${&lY5Pu>P3I0z@#xhCrw>lCHYnVEy2^#)v-HL*#3sS3_XC!e*SK_YH_3zB zOW%mrsFOQ`6wFR_h=7T)nl=}D;}tg-zEA;I?|o!$=Q#6wdhFRg&fZ;!k6*8I_RtK2 z6x?|5nPj3F79?nfg^+mpuFr>+gaktqkuvpKo3SFEEU(k4DoxZ-T^G9a+^gWR+NFF2;*@NUk_P{(a7gho*!b8mMm|*eFTe|BT zPMZtUlO6I{#iUi(gmAAgudxtTL@9v>ln5k{_^sM^<%Nc=BNLGVWk(h$707`~APeMz h2>w+`ViYwa`U&8QX@yPWti%8S002ovPDHLkV1mwr|55+| literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/xhtml_add.png b/base/resources.pk3dir/gfx/icon16/xhtml_add.png new file mode 100644 index 0000000000000000000000000000000000000000..bbaf784f2181f9953c961d15f8d1f16cb500a353 GIT binary patch literal 703 zcmV;w0zmzVP)(EGn5{?^v(DSQN?@3iQqlt zV&qP6UdRh0^GcozDbv<>l=;IDH9{~%4GD%9!>i)G;YIO5DMUGQ=L;#nP1J;-AZkcZ ziePwAycmTjP6CBDoG67?=2lYjs*o~m`eK( zTRpi~G!x>?2@l_7tXn#ptB=R1FGcLz+De*4R9(P;%mq|olYn_Jl2)*0FGI2X}|BG5GvEE%ROx^&B6uon6g*`0gmY;zV)Y zC`56h6rwa~FMD=uha_g#ii7ms-bX^r`OCM6Cnklw2sG3uG|WzDDkn5o5?U$=t(BCv z#u7iOUnoTtcC9$bFTFiySlZS}6noO|x#!f)kC->qDOL#P6>|X!#e%YI)fmI00}PEm z;Lx_Sob2CAeKHHv5|NqlFWmBxr8jdaZK;`QgJ3_N?lhqvQ>k(u#7x(_Tk l3G4?NfJxx=;Hl9=KLOX-UDpSegn0k}002ovPDHLkV1k-NLT3N~ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/xhtml_delete.png b/base/resources.pk3dir/gfx/icon16/xhtml_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..157b5201d0cfc97af349384e73f5edd3711b03ea GIT binary patch literal 696 zcmV;p0!RIcP)vB`%|NH-brpS$=_W49+#!Tdxp&T<5pS}6j_zO|Rd&P<1 zJ)~l!PHjhqty7=OZRvz<|UBRAJ-t+5A+U3OFCIB#@g- zjm;~XcrsLB+v?fWoO1rwD9#(nRKN_9sX*o770Sm~GqAJB(2->*nL|e|4ZO__fM#dbOSDYx$ z8<{9hluVQZ{kzzG^aQ21eK6V&bLR3b?%=_L*Tj{okY<6VVxFunqUa-hy&)3eC5Km| zCHX*cK_~1w$!~G@LKg6ycr5i?x<86}L!DxoU|um7AX6+TTMI4JUf!eO&M{p2i5gI? z|N{EUV<6Kr2qqFjqyc|6X(o;fr(CfH;s zUVf@EFkI%)w)r?w`Ul3)JWy~V)SNP>R74eKG!)2vq`5KS{H?Dfz^SXFTz|2Lk;-1$ zXB&&#o5+KrnNY}_@Z^2Q#_kqw4vy2*kZ`nb9%(V5>LLbYE>aiI!nS1`>0igsEW?F} zWs$U+8@O5&V z_k?IX9ImjwYbIt;bpnl^9V-qJO^F&&j4$O;RxR8@)#nV2ZYI&oq`zu`i+8?Jb&(TS zMsT9IU=$0UXv(J_?+7Z020{!}+yrYEZKWD&jQ8y)txO2HkF+)w@eK)0AtB5##(W)# z!u(mCh(@9*U&|xREp;$7`iQ3=h8cf&fu#G`bF1fq1w)-;Ua+8S*?pM0_jvWx#nauk zoSv?oJR5n;-B*KTPtRi2PLluq#+7FZ*@n*EmVvkTK6_>Rmvi<8_ zQ%h@8K@|Sx-ZT$MQld?(Bp9R$QmIlwlExsMGBFkk5EJsf=392fG_LNsZZ$7WYF<_ zEPr2t6OKcQ6k_q_NgUpjT9;EpDosJUC<%qsSZck+eC-yrVmQ6?4&rPG_vU^g)}yt2 zN!jt2q`)mvSu!Woauj3PoA!LQk;B%sLeP=j0H+S5QCVzbax{&mAK}UC2BweXkcu@18R6Y`Y4g#v(kZ;fa03-hOr^_hi;}|KV zP}mm7uE8V%K|S*%950l3^V!3p;VpRnu7PA9!7+D1#p$UF$Z`PLEUNg-l zn-{_91R4_~8O(od;l%!|Rdb{KjT|&Qax`ONP|@bYmkz$JhW2cY>?-7NngORP(|A>F z!F8B5c1V>OFq7Fx@VE&8Dyfd&)a?G0i(w1a~i{jWpGb(#8fDK=L zuh#;SY-=JTH+w=OpA!<%{*waR$$u8x>~rp|Kh9U4T}Uu~^#A|>07*qoM6N<$f)0&A A%>V!Z literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/zoom.png b/base/resources.pk3dir/gfx/icon16/zoom.png new file mode 100644 index 0000000000000000000000000000000000000000..908612e394525fc2e52a7e9b94689c25ce167381 GIT binary patch literal 692 zcmV;l0!#ggP)m+BBgry{~j2fHLegbHP( zrgXNbr0}2;^nywdjLjZe?uxtrd3D(pZH@fFFc0{BW_~jxoO1w7-VX;6vK@ROA$$R6 zEmo;Ht-Mj|>5jUy{bQ^V5@53LRI8AgLpUm|m+15sqcz@QtVSo|oz7ArM8?pIn+>gN z0b=4_b5O|4A*;Q+vc9Vqr~%3V155*NV~@gTz}KSUiKB-uJzjMZ>5%Q#n24H!V{ zTY(LLAE*NAHZ}C#wnj%Bw5OFIkRhkkAW#kDC3j9Wm0YXRaXlyyp>#mVfYG)eC;@ab zDb=T-BCAY4LI(Z@GOTr2V_A{pRwSmz+8Be>CjAw(=gnbVWAeguvZa93JmL(EDxv1m z0OP4q=fpAK1Mq!C2`OkEn37o;m#wF#(t(8Pu#S?2f#x<~4EO{@fmm`p9veD6RZ_jp z@Au4};q&`XuKEYgIiB4((kgxOs#YdqJw0fY>9^K_agEu5+$#k;w#%I2N>n_?)YIqu z`tq&#_^p?-%K*U0^}|7+9U(&k0?s;=r=uCZ%)H9_edH8wK}gB(nUB1FFk+2Ol%BXV zHoFY`D~2x|2m%7v+TE=2L@ zAc44q=tejYU5HLZGooZ=NXsV%)bU*sTokj@jZSo^9&w{ke7#VNQ*1zG!rIRk_@ zCqOr;g6B6CM1oPv1(~U4k@Gd+5tN0(j@GA*K*busv3Lb0UyXuowiRkTRZ#85JN!eC z_8ZVW>+upx5C#N|BTv2dK_EW@%(@F6yu1sZv>T3gm&*mIkvej1R4=RyYw#mS zx}c)#2z<)=VQ1|=ux>5PwjVE+J!Q84EQyG-j9SFYV*6AQj$Gb(7!KJE!k5iQ@O3K$ z@0NQZ)>b7&TaFd~Ciolk*Q(7cL+9cB`Y;G@rr`tk5Hdjv+))zSdlF#gI!>6`zB<@i zaKYP!9!Pl&5VMjydlq1x&}37{RQY+SSBXX-w?kCLKK%bXFYU6{?d+nH00000NkvXX Hu0mjfTSP*+ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/zoom_out.png b/base/resources.pk3dir/gfx/icon16/zoom_out.png new file mode 100644 index 0000000000000000000000000000000000000000..07bf98a79cfea526e250703356dbefdb6b80d166 GIT binary patch literal 708 zcmV;#0z3VQP)TNkCP1&*^7LC~A?iZQEu_hKZoQoXI zA7tfTv}|~Fb8b^XuP>qvDk=)P)vYKtT12;}bKn-mwHWl`1Bb)&{XXC4IY$Nnvj5@N zfekg1Y}gcI!)Cq|u?lR+A{2&=d~S$}&0ei1|7pO6jkZ$6%&{R8TNpk>=dV#j&aWqO zgE~4pNU_-giktFkY-J5_XDlv`7+j?n3mXtxgadILp+c<9cr~t!x1LM6m69Z~V#pLL z22Cs~BoIdtZHTjo7Q|_U0a2OmSF=gCGFB$RVZIP(pixmBqE!^15yd!#9Z{Wh)zB%o zikBFa!WJPvMB(noe(U;k1e~Y|r$}@wh*Ymykd6>E3t69z5DT&Jq-fSG-dPdU{SG;i zbSb3<`RfKgJD|lQC`6(Cdut1PbDV&$M=Y?U)x)A(0iQN+gAeOBg2Z6fr$_Is!%M70 z=n*z7{*s%3rO7yazIO)}qa&~o@WZ=R>!b#mOSR zlCR8M*iRy2j7!PmWiiegA>Og~W1?FLk0*NI^}`$RWeoA2D#>avfU zuDZz!?W!wBnqf_t$_9b5Sew(`HLz}C;AQ{LdEVKA9{6wXIXu7f^&Canr|g_YrBOM$ z=Q*2?rB4VW;zAsOBEQ%dt0c6*8tF13d0S}zS@Y2}x^9-1iplkLtx2F=Zj{~>jZyn%7bf$6gT#^Ft z3wub~Eag*j5I$aC9-)a6M*SOzJSicd77+|@Vmz9K`~GSb<~2D3`IP&4vINT7If8F& z9pjM#B2V)Ogx4_mAdTMs6s~m46UEEYqOFj`_Y$#-lb6feC=@FAnyX-LVGD`5?|40# zgVXhfkTz{q<-XSQ^|KZaTHCxhcB&8jth^7rRB$#O-`RKW-hL~|d2Jzn&>Oyv2s>Pzg9G{g z51pRYRVtNKuh-RXx8?HqiZqu%Q60B`>NxzPAcz!(Uo5}XYH2VSXfl~-u~>*at9}O< zx9mlz+`Ok;Es8r`#>lTKm&@vOIvR~eilRuH%|^@R($LoLKl|9hY&O$+z1C{A(sVktT@1aKN~IK>2MWK33g&_QbzX%+L5W1ddhpH+^Z8uk z@mRy*P~C3V-k5tYoldJ*EUNIiptJKcc{T4JIHrq}$z-fuv)NR?-&e2KvxQhVKF&1? zRI63Fl}bfBzVB~q^ZdYa;?#UTFSpTX=sLV_!M6ZI4^^p77lfiK$K`U9nV5|knRN@d z?b(K{*p4mPmaRzw{qDniV+D4MrI@X40VAIoAQf^U8L}ZA@(}?s5Cw4%3GkJ4pb->d z5g4J_h%qn#M!*ml1A{PQ>h(G*l?qCw5{SPfbUK~N#c(*pcs#~zHp6PQ!gjkwZ!ZlCX@p-9KA+D8 z?smK3@p!=Ma=GAeIAFKi@v(P^3-b6PY1gDJmrJ3A!(l`s5wHe>L3q7hIGs*tng;Vk zrD0N4QrGLXP_x-Aa=9E> z&05W7GfXBEX1$pd(`vQwdc8=e)A0NKFc=JTF)S7f>ypVNDwPV_?KaBgGBb2K-BgC~ z%Vx8vR;wtLN=O`^!1Hz!8~dkty>~V-54~Q`e(`u5jYb3AZWqU&KC>?O`!8s&@18+^ z_Z`Jzaf~6$GAPe{K95ePgH$So@b(8>-Si*le_XbD2)_RUdFvZqyj)`s>W4<7fqi9_ zb%{iRb$8tX#Jv4?kDE>p*SCN0X6Fd6c2Du+*99{u50A&gy$A+_Xf~T5h8UyK2!p|Z z*%bSl%b{Mc0aDTTAfZO|92n|;CJ)tlq||W91g=~v$3Z#HqV}F_xXG?^PI(@I;~dg GRQ&@w5^^;F diff --git a/base/resources.pk3dir/textures/ui/icons/disconnect.mat b/base/resources.pk3dir/textures/ui/icons/disconnect.mat deleted file mode 100644 index b544eb2f..00000000 --- a/base/resources.pk3dir/textures/ui/icons/disconnect.mat +++ /dev/null @@ -1,9 +0,0 @@ -// Vera Visions Material -{ - diffusemap "textures/ui/icons/disconnect.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/icons/disconnect.tga b/base/resources.pk3dir/textures/ui/icons/disconnect.tga deleted file mode 100644 index 7674e5e5a179f31000cb53fbb640024f4660e8ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1042 zcmZ{jTTGK@7{|-RghYdw4H7jW!+`O|#2bwvNJ5q+Nc6&Nf>q05wxb*dECdoR21wGb zwIJhs5C|=_4X2IqQsC-|LDoFKlfLe3apwCF-^ULvEQYR39Tj9 z3V(kGp`my9@FP3>_H~ZG&$qR;(b(8XWo0F1vzdYdBjFLXW?{qq8 zX=$OhwwAK8GD1SEf*T<|{;{YrLqxetterp00?zej+91 zXPnLzPM+-N`0*bJJ9=00TXKGv%cbnCy1H7)y{M>2VRLeFSbOn;^^Hy8VN7H;OmJ{F zQ`4)M%r@cUVWi~y`udce%bm%-d3kvvpDgrxJ!|Xh{QmMK+uPe>uX994_p`IJgSE{j z@6R#G_w@8oT3U+iE7{D#Z$zc6ZqolC|n@H%k7fYy6+&yS|cmjW2XszD(1T Rny%-1s*a4TuSx~){}$7*niv28 diff --git a/base/resources.pk3dir/textures/ui/icons/encrypted.mat b/base/resources.pk3dir/textures/ui/icons/encrypted.mat deleted file mode 100644 index f84cfb2e..00000000 --- a/base/resources.pk3dir/textures/ui/icons/encrypted.mat +++ /dev/null @@ -1,9 +0,0 @@ -// Vera Visions Material -{ - diffusemap "textures/ui/icons/encrypted.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/icons/encrypted.tga b/base/resources.pk3dir/textures/ui/icons/encrypted.tga deleted file mode 100644 index e3973aabf22e410d6ceaede6f503b1ef7c12c1fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1042 zcmZvaQAkr^6vr<;)hZj&Lt1OjiJ;3EK@{|mB$`UN2gkUsCA&;aw6c5%#EKCqG9`2w zM461WM&)v2ZuMd@x6w;NYnwjgz_IOdj2`y>@B2odu6yr=!{LAK|98&$?)^CK0LLCB zr{wAn64k~+-O&xBZ3ulMqv#QAXz#y)i$)X9UpGM4(FM)rHXJ%x3+AuRE!JTOZ#?)} zEMaA57q2%HaI9}&!ncNDQsTCGFyeOg7iTt=~2M4?bXI-N#5 z9!EGFhS%%Gobx$)ZjVFR*d*c2W;6VL{~n*u=aEXKDtssug2&^*?1Gc<_i?PDQJ!Dj zpP$R+kW3~KjYbg+2H|$Q|MBCf(P(A)U?5PLUn2Wwvsok(2}B|h1W4WGa_#f#1_^KC z`{7veW2^KBKJxvRHj|k97RSTDXWVhW$4%!e7@si(D=@!9hz6u;g$FJlTzY zK5h;-HKCq8-xzmLCu-n9sL2d3efvt||H$c!mlJPyo_TWB2j?E{Ob>7R_{!DmOqf)7$UazCsY@*ZYi0yDVi2uEQwOWB1(rUF34u=tmL=X%H<($vw(QdcJ-tYH+ z>1VSU27`fMSr#&x4644XnfG^U1v8 z@i<5-m4egh6g};%ojFy{*`Lp6`wn@%UOeJ*xn#C_*O*iF)9F<7tbuU($=Z{q7#mjKN)Le(v->#_e{)UoZ#zrN8QVeuf|YfBs+d3q%Jz AssI20 diff --git a/base/resources.pk3dir/textures/ui/icons/folder.mat b/base/resources.pk3dir/textures/ui/icons/folder.mat deleted file mode 100644 index a65c42a9..00000000 --- a/base/resources.pk3dir/textures/ui/icons/folder.mat +++ /dev/null @@ -1,9 +0,0 @@ -// Vera Visions Material -{ - diffusemap "textures/ui/icons/folder.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/icons/folder.tga b/base/resources.pk3dir/textures/ui/icons/folder.tga deleted file mode 100644 index c8936750b563e9736ca581c2d6c7a3140f1f16ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1042 zcmb8tUuaTM90%}=FB=4=B|$H;JxviN2+15vMO1wAB})2-FAJBhhG7u|wNVt&AJ#)f zu$W~@Lh1%eVoX;mZ7xZcS}2Mjf{KDKJ_+ACXLvVTLR~ogIQO2<@B4#$7>2|29v;JE zMuvO4f2|x22V$`p$0jE6KW2P<943O(YTtx+gt?!63X|FJ@;iL9f@d zp14>nhEl17VzG#PK96iRi*!1Tt*tG@<8eeH5n9*Q)~Vl{uhD4GYPC?W*HNujQ7)HJ zC=`&%WRT0{@MR;3z}tIxU>n22i350I8G~A_X7jaLEjpbJ+U+(PjRx(L&E?@=p2uUG zh?>RoTs)mV2$!9YsPj~xC$n_BT~sPHgx=l9Bb%6-hiAEXe&M%q@bUh}Aq4LZ(Y5_y zuFp#(60F`j%;r3s=3@CWA1gO^P5jjazIsg{wpm_>N~L1w7Yc<)zBmG>jYo4Ie$1@gdEZi* zB0c>|7O6fZ5Q|hiD<~3jFPzKzb5x8Bq&N!^*atl~J|loD?OYe8C>M$$B${riLInGL ySI diff --git a/base/resources.pk3dir/textures/ui/icons/hdd.mat b/base/resources.pk3dir/textures/ui/icons/hdd.mat deleted file mode 100644 index 8d41b784..00000000 --- a/base/resources.pk3dir/textures/ui/icons/hdd.mat +++ /dev/null @@ -1,9 +0,0 @@ -// Vera Visions Material -{ - diffusemap "textures/ui/icons/hdd.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/icons/hdd.tga b/base/resources.pk3dir/textures/ui/icons/hdd.tga deleted file mode 100644 index 1e5d9a00e03354a83854f29bb9c14cba68c90637..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 760 zcmZuvO-NKx7`>K~S%KiTg^Lz0N@gJug0o6tV0?+@@I(=DRiO(N!DNVeGf$CG$qNC{on@#O6e7I#k&O&-CV`-KPYdED)q$qA5)GhdUF(k~+(kE4hx6bM)gQy{suq+ryg+DmAJL6N*j+v1 zL0IJ8Vn%w4JBZ+N8iB<$N-A`;`QM|mBLK}E#haBhK5QPr-qb5ta-^|0nYlU#@GP_q z$LKda9Qumdjv+MrrVz90Mb|`>lRIN1~%sfR(G7tlh54dHpqt@)XZdn5t)e^V>fnO z9voafV*m01#<4jzaJqf)_&$D&taisAgLpEqjOVa{>-HI^9v_aby=b3U{9_=Ygl1rV zB^;l!<}rTl^~3$}iu1b{bXaC1;62kz;rPs~mT|BD1NSfQ@I3j^GCUapC)3dGx%l}7 zJ>!8u0B@gPcz*ljBctO}yAKvmrlEK=^}cK?W!y}>rn0RsLSFjfVc^PYbqJ_8w1tDB zwrhxo2%Ktd-N1yTR58hE8A#2_g>CO&oq~$^9lZ^E^G|=oNTq5ai4;^5wk&nAeO+r%NEK1g03Y*@z#`7e8_K1;v_e~{E7KJhrB@Z`3bh&H8pnNlSU8}!$4y=pUDqL= zgk*W(G!_B2~Xu+XxTxe(mja9y=D%ZRj-IP{lyiJRUGAqg-@os5#8*-@{0ST z4$2AoQ||g^9+y{hAf7uMLVBkcu`M4~BdyTbF&hPmx6olvtV$mqleoLz08^Zv1(7d| zK+6muvE7NtdK(tQ4zquxn@N8qpI-`KhTBpY=NBOq^iiojk?g`+v|UKK6Vm3*x~TS_ zDmChtDKp^w?FShr15=+GyVX0M$>8J+&(sx9hK`?T)4@<+Mx9b8C;Dc`)bT*S@(%bU B5y$`l diff --git a/base/resources.pk3dir/textures/ui/icons/important.mat b/base/resources.pk3dir/textures/ui/icons/important.mat deleted file mode 100644 index 54237aec..00000000 --- a/base/resources.pk3dir/textures/ui/icons/important.mat +++ /dev/null @@ -1,9 +0,0 @@ -// Vera Visions Material -{ - diffusemap "textures/ui/icons/important.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/icons/important.tga b/base/resources.pk3dir/textures/ui/icons/important.tga deleted file mode 100644 index f618e1e08ce062833f2c451cb96a5ec168c5c187..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1042 zcmbV}(G9~O3`DJd^)n-Mgp9*DjKXKe=pgLk`V1ElL=qY#blCWvO(OCVu0KsUi3Tn@S3mHVOv>IJG&opHGg8^_joJn;eiE3eE23~g9A?w rva>wvdmi!4{FusXFf-q=_qCkgk7sYQ?ty;X6Mb7AXZC8fukrW?XXgxm diff --git a/base/resources.pk3dir/textures/ui/icons/music.mat b/base/resources.pk3dir/textures/ui/icons/music.mat deleted file mode 100644 index 4853cd89..00000000 --- a/base/resources.pk3dir/textures/ui/icons/music.mat +++ /dev/null @@ -1,9 +0,0 @@ -// Vera Visions Material -{ - diffusemap "textures/ui/icons/music.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/icons/music.tga b/base/resources.pk3dir/textures/ui/icons/music.tga deleted file mode 100644 index 45933bef6c2581c0aedf2189b6cdc0f857bf1fbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1042 zcmb7@OK1~O6o$ulcV;1?=t6KQxX4@;K@da`L=+mQcQQ#O$joh*x)206NYd#hHR5jgl3@i@U>2wJxfMfHl&rl!ECWqBIHYPzSy^SKm4DH zO5YUpD03gMi+6_Z(qR5JGgLzSYP1sZ1zVgeDSc26em#+ygV!`U4#;IJIau_6XNM}PLffoc);YB$lZH>*5lWU`EgHwS+%Sj*- zP0Mo*LdAkMeb{n-?4YDjd{C07kFBXgFcDpE*O7nC)RBVsTBuPT6)qvC-TIKg$#9?l_O=Qu~@f^xj=ICIc%DaK+k{w{jw^D?kf zPatuS1oJCGs7N0w9^h`@WgkT|0N-Mq9XryFA~q%==-Vcv~jS@}_A_-UsuB>8u|{e7Rg&9LMsB zDT@aQShAh3*K3>o1(lz2ZU%_ebv+1*qWCXR-4H=<;{EY>w4B7A7J^fsrt*-YvMe*- zwyilelO)NY3GqgW8quMEx~?;1d?iZL^du+coEV`|O-FO;dG95dgajP;2B9v2&?w~S zn3ZKYRKk&9hd|FELJbPdtE&2e1pEC1uOrrdAN_DR*xP$(Tk=eh_NSXPE)dB7g0!#q s(T$7{%vemjdTWj_<-u1}e~P-7N8{Mj;)#7bF~35!U-h^Qf1 zw3OkRy_!>}(hFG(Eh(}&&C=0YVw&|u{B@r@HW#6I;D68Ip8NZs`#kr#3dJIYKSC5C ziZzS%dcDH0$jC@hBjp7vG&B^oTD>40IGKmxPCNNG+c;C(D$fwCPN&0SvB-J8TC3Hf zPe04uHzO3(&GLdxO-+?O=Bhdg1)8~sW5pqFy9k3Srx zq~ClIb9puuA10`-Ddf>DBZJpd=qZZFdPGfOtdFm^KE(NblD=Utl@=d=DLGu4m&ogZ zQAWn0wD%9$txg&Wl5m{g#e-v8DAKGYPMUA)c*d6>lQ`XD0bZOP;ql_L8_yJ&U1JpY zd}UvCGdCoU#zPy)iVmYVFO7cZ0N(Lmd>nFf?{T~Q{RQ8UwT!`lR0sjo}QLjhr=P?tE#H{k9WCT^8X{{ t0Ov0}9uJwBnE_UshnN|xU|x6xORQNiVs0=iUV3I`CfLW{pDzcV{|nOLSMvY> diff --git a/base/resources.pk3dir/textures/ui/icons/servers.mat b/base/resources.pk3dir/textures/ui/icons/servers.mat deleted file mode 100644 index be5f99fd..00000000 --- a/base/resources.pk3dir/textures/ui/icons/servers.mat +++ /dev/null @@ -1,9 +0,0 @@ -// Vera Visions Material -{ - diffusemap "textures/ui/icons/servers.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/icons/servers.tga b/base/resources.pk3dir/textures/ui/icons/servers.tga deleted file mode 100644 index dc70f484cb6b04b4a7308ebbe1355b6690b394c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1042 zcma)3F>ZrE5Ih+nrQ`{IK)&I)!c`iVE>c=a8e2&kYPV_JnU5d}9zaicfl=PDW-bg` zF2H%E)h)-)%=@U9p8mw^{vyw?AC4JCdGw3l8yc0kaJs;YV~eEYZm Kx#!e5(7ypJ$(cO> diff --git a/base/resources.pk3dir/textures/ui/icons/shred.mat b/base/resources.pk3dir/textures/ui/icons/shred.mat deleted file mode 100644 index d5d0c37a..00000000 --- a/base/resources.pk3dir/textures/ui/icons/shred.mat +++ /dev/null @@ -1,9 +0,0 @@ -// Vera Visions Material -{ - diffusemap "textures/ui/icons/shred.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/icons/shred.tga b/base/resources.pk3dir/textures/ui/icons/shred.tga deleted file mode 100644 index 66aa75521261ad7fbf485c940678197a677c1950..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1042 zcmb`F(G7zz3`DJd^^*}g0wZJ$#$hxzbA2W+wE$IZRV3?@;Cr?MW;f%RY_iAQ-R<8I z6?~rO!2ZUT-?q(DWBn}$zk2wDqr6o$Yf%5FhkkO-b#;#rLy>jGYVB43z+t8vJbq@7W&7QU5Jq)xma;C_|S5^K^2f>iym%@-*@yi24=OR~zSd{|{ z2L1H?$qUQM_c<~4e$uOE^m6zx>Ez)CYzAVcnW3co;XvQA$)!;m}-{J7aUbEKx Lck6mDaIf;8R|;V3 diff --git a/base/resources.pk3dir/textures/ui/icons/socket.mat b/base/resources.pk3dir/textures/ui/icons/socket.mat deleted file mode 100644 index 787d263e..00000000 --- a/base/resources.pk3dir/textures/ui/icons/socket.mat +++ /dev/null @@ -1,9 +0,0 @@ -// Vera Visions Material -{ - diffusemap "textures/ui/icons/socket.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/icons/socket.tga b/base/resources.pk3dir/textures/ui/icons/socket.tga deleted file mode 100644 index 49077058f13e4c3327c91b2961251161c58b1dde..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1042 zcmb7?!3hK*3`J#6dz=!s1WVX5EXPtTMX(KfaeV`UzoIivAdu*PF_Ad;a%P7++~?i1 z@61C84T~|heveOet8;i*+*tO~rwqBvxl#LyWe?DxS0?v9;QRg74p2iGjaR!io-3pA bs9WXAXuQ&o=gMe2>Q?!L+4{So-WKx%`A$ER diff --git a/base/resources.pk3dir/textures/ui/icons/track-full.mat b/base/resources.pk3dir/textures/ui/icons/track-full.mat deleted file mode 100644 index c09dfb11..00000000 --- a/base/resources.pk3dir/textures/ui/icons/track-full.mat +++ /dev/null @@ -1,9 +0,0 @@ -// Vera Visions Material -{ - diffusemap "textures/ui/icons/track-full.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/icons/track-full.tga b/base/resources.pk3dir/textures/ui/icons/track-full.tga deleted file mode 100644 index c41ad75dfffeb543bd23c73ea0d0917a2b71a6e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1042 zcmeH_u?@p83}HC?4tw0) z-696VBO>RjmZtaapp-I^Qd;w_bey3@L!cwiIWIlA=D?3YkB<23fA|07eQRy{fN#P# z{)r=veCJ%f=sh+5+xxzdvmZ!fwR$~?M$-Kj{Iv%Gk(JgTN@zruc^59hIs%0 diff --git a/base/resources.pk3dir/textures/ui/m_bottom.mat b/base/resources.pk3dir/textures/ui/m_bottom.mat deleted file mode 100644 index 684b2af1..00000000 --- a/base/resources.pk3dir/textures/ui/m_bottom.mat +++ /dev/null @@ -1,12 +0,0 @@ -// Vera Visions Material -{ - noPicMip - noMipmaps - - diffusemap "textures/ui/m_bottom.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/m_bottomleft.mat b/base/resources.pk3dir/textures/ui/m_bottomleft.mat deleted file mode 100644 index 3e2ab814..00000000 --- a/base/resources.pk3dir/textures/ui/m_bottomleft.mat +++ /dev/null @@ -1,12 +0,0 @@ -// Vera Visions Material -{ - noPicMip - noMipmaps - - diffusemap "textures/ui/m_bottomleft.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/m_bottomright.mat b/base/resources.pk3dir/textures/ui/m_bottomright.mat deleted file mode 100644 index a5ec44ee..00000000 --- a/base/resources.pk3dir/textures/ui/m_bottomright.mat +++ /dev/null @@ -1,12 +0,0 @@ -// Vera Visions Material -{ - noPicMip - noMipmaps - - diffusemap "textures/ui/m_bottomright.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/m_left.mat b/base/resources.pk3dir/textures/ui/m_left.mat deleted file mode 100644 index c4e4cdab..00000000 --- a/base/resources.pk3dir/textures/ui/m_left.mat +++ /dev/null @@ -1,12 +0,0 @@ -// Vera Visions Material -{ - noPicMip - noMipmaps - - diffusemap "textures/ui/m_left.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/m_linebottom.mat b/base/resources.pk3dir/textures/ui/m_linebottom.mat deleted file mode 100644 index de094343..00000000 --- a/base/resources.pk3dir/textures/ui/m_linebottom.mat +++ /dev/null @@ -1,12 +0,0 @@ -// Vera Visions Material -{ - noPicMip - noMipmaps - - diffusemap "textures/ui/m_linebottom.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/m_linebottomleft.mat b/base/resources.pk3dir/textures/ui/m_linebottomleft.mat deleted file mode 100644 index 7a4dc403..00000000 --- a/base/resources.pk3dir/textures/ui/m_linebottomleft.mat +++ /dev/null @@ -1,12 +0,0 @@ -// Vera Visions Material -{ - noPicMip - noMipmaps - - diffusemap "textures/ui/m_linebottomleft.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/m_linebottomright.mat b/base/resources.pk3dir/textures/ui/m_linebottomright.mat deleted file mode 100644 index d152923d..00000000 --- a/base/resources.pk3dir/textures/ui/m_linebottomright.mat +++ /dev/null @@ -1,12 +0,0 @@ -// Vera Visions Material -{ - noPicMip - noMipmaps - - diffusemap "textures/ui/m_linebottomright.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/m_lineleft.mat b/base/resources.pk3dir/textures/ui/m_lineleft.mat deleted file mode 100644 index 6fc7da2e..00000000 --- a/base/resources.pk3dir/textures/ui/m_lineleft.mat +++ /dev/null @@ -1,12 +0,0 @@ -// Vera Visions Material -{ - noPicMip - noMipmaps - - diffusemap "textures/ui/m_lineleft.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/m_linemid.mat b/base/resources.pk3dir/textures/ui/m_linemid.mat deleted file mode 100644 index b98f68f0..00000000 --- a/base/resources.pk3dir/textures/ui/m_linemid.mat +++ /dev/null @@ -1,12 +0,0 @@ -// Vera Visions Material -{ - noPicMip - noMipmaps - - diffusemap "textures/ui/m_linemid.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/m_lineright.mat b/base/resources.pk3dir/textures/ui/m_lineright.mat deleted file mode 100644 index ed43bb53..00000000 --- a/base/resources.pk3dir/textures/ui/m_lineright.mat +++ /dev/null @@ -1,12 +0,0 @@ -// Vera Visions Material -{ - noPicMip - noMipmaps - - diffusemap "textures/ui/m_lineright.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/m_linetop.mat b/base/resources.pk3dir/textures/ui/m_linetop.mat deleted file mode 100644 index 2c6ebcaf..00000000 --- a/base/resources.pk3dir/textures/ui/m_linetop.mat +++ /dev/null @@ -1,12 +0,0 @@ -// Vera Visions Material -{ - noPicMip - noMipmaps - - diffusemap "textures/ui/m_linetop.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/m_linetopleft.mat b/base/resources.pk3dir/textures/ui/m_linetopleft.mat deleted file mode 100644 index 409993d6..00000000 --- a/base/resources.pk3dir/textures/ui/m_linetopleft.mat +++ /dev/null @@ -1,12 +0,0 @@ -// Vera Visions Material -{ - noPicMip - noMipmaps - - diffusemap "textures/ui/m_linetopleft.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/m_linetopright.mat b/base/resources.pk3dir/textures/ui/m_linetopright.mat deleted file mode 100644 index 03a042c0..00000000 --- a/base/resources.pk3dir/textures/ui/m_linetopright.mat +++ /dev/null @@ -1,12 +0,0 @@ -// Vera Visions Material -{ - noPicMip - noMipmaps - - diffusemap "textures/ui/m_linetopright.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/m_mid.mat b/base/resources.pk3dir/textures/ui/m_mid.mat deleted file mode 100644 index ad647df9..00000000 --- a/base/resources.pk3dir/textures/ui/m_mid.mat +++ /dev/null @@ -1,12 +0,0 @@ -// Vera Visions Material -{ - noPicMip - noMipmaps - - diffusemap "textures/ui/m_mid.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/m_right.mat b/base/resources.pk3dir/textures/ui/m_right.mat deleted file mode 100644 index 60ac7d95..00000000 --- a/base/resources.pk3dir/textures/ui/m_right.mat +++ /dev/null @@ -1,12 +0,0 @@ -// Vera Visions Material -{ - noPicMip - noMipmaps - - diffusemap "textures/ui/m_right.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/m_top.mat b/base/resources.pk3dir/textures/ui/m_top.mat deleted file mode 100644 index 318ceb31..00000000 --- a/base/resources.pk3dir/textures/ui/m_top.mat +++ /dev/null @@ -1,12 +0,0 @@ -// Vera Visions Material -{ - noPicMip - noMipmaps - - diffusemap "textures/ui/m_top.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/m_topleft.mat b/base/resources.pk3dir/textures/ui/m_topleft.mat deleted file mode 100644 index b892a3a1..00000000 --- a/base/resources.pk3dir/textures/ui/m_topleft.mat +++ /dev/null @@ -1,12 +0,0 @@ -// Vera Visions Material -{ - noPicMip - noMipmaps - - diffusemap "textures/ui/m_topleft.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/m_topright.mat b/base/resources.pk3dir/textures/ui/m_topright.mat deleted file mode 100644 index 66ed1d59..00000000 --- a/base/resources.pk3dir/textures/ui/m_topright.mat +++ /dev/null @@ -1,12 +0,0 @@ -// Vera Visions Material -{ - noPicMip - noMipmaps - - diffusemap "textures/ui/m_topright.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/steam/icon_checked.mat b/base/resources.pk3dir/textures/ui/steam/icon_checked.mat deleted file mode 100644 index 28c0f111..00000000 --- a/base/resources.pk3dir/textures/ui/steam/icon_checked.mat +++ /dev/null @@ -1,9 +0,0 @@ -// Vera Visions Material -{ - diffusemap "textures/ui/steam/icon_checked.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/steam/icon_close.mat b/base/resources.pk3dir/textures/ui/steam/icon_close.mat deleted file mode 100644 index 0bc018c4..00000000 --- a/base/resources.pk3dir/textures/ui/steam/icon_close.mat +++ /dev/null @@ -1,9 +0,0 @@ -// Vera Visions Material -{ - diffusemap "textures/ui/steam/icon_close.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/steam/icon_down.mat b/base/resources.pk3dir/textures/ui/steam/icon_down.mat deleted file mode 100644 index 6c26d055..00000000 --- a/base/resources.pk3dir/textures/ui/steam/icon_down.mat +++ /dev/null @@ -1,9 +0,0 @@ -// Vera Visions Material -{ - diffusemap "textures/ui/steam/icon_down.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/steam/icon_emptybox.mat b/base/resources.pk3dir/textures/ui/steam/icon_emptybox.mat deleted file mode 100644 index 2fea5ae9..00000000 --- a/base/resources.pk3dir/textures/ui/steam/icon_emptybox.mat +++ /dev/null @@ -1,9 +0,0 @@ -// Vera Visions Material -{ - diffusemap "textures/ui/steam/icon_emptybox.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/steam/icon_radiosel.mat b/base/resources.pk3dir/textures/ui/steam/icon_radiosel.mat deleted file mode 100644 index 1dbea4e5..00000000 --- a/base/resources.pk3dir/textures/ui/steam/icon_radiosel.mat +++ /dev/null @@ -1,9 +0,0 @@ -// Vera Visions Material -{ - diffusemap "textures/ui/steam/icon_radiosel.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/steam/icon_radiounsel.mat b/base/resources.pk3dir/textures/ui/steam/icon_radiounsel.mat deleted file mode 100644 index 1458b1e8..00000000 --- a/base/resources.pk3dir/textures/ui/steam/icon_radiounsel.mat +++ /dev/null @@ -1,9 +0,0 @@ -// Vera Visions Material -{ - diffusemap "textures/ui/steam/icon_radiounsel.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/steam/icon_resizer.mat b/base/resources.pk3dir/textures/ui/steam/icon_resizer.mat deleted file mode 100644 index 39a214b8..00000000 --- a/base/resources.pk3dir/textures/ui/steam/icon_resizer.mat +++ /dev/null @@ -1,9 +0,0 @@ -// Vera Visions Material -{ - diffusemap "textures/ui/steam/icon_resizer.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/steam/icon_up.mat b/base/resources.pk3dir/textures/ui/steam/icon_up.mat deleted file mode 100644 index 3a39aff6..00000000 --- a/base/resources.pk3dir/textures/ui/steam/icon_up.mat +++ /dev/null @@ -1,9 +0,0 @@ -// Vera Visions Material -{ - diffusemap "textures/ui/steam/icon_up.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/voice_off.mat b/base/resources.pk3dir/textures/ui/voice_off.mat deleted file mode 100644 index 29655cf3..00000000 --- a/base/resources.pk3dir/textures/ui/voice_off.mat +++ /dev/null @@ -1,12 +0,0 @@ -// Vera Visions Material -{ - noPicMip - noMipmaps - - diffusemap "textures/ui/voice_off.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/resources.pk3dir/textures/ui/voice_on.mat b/base/resources.pk3dir/textures/ui/voice_on.mat deleted file mode 100644 index 00c47da0..00000000 --- a/base/resources.pk3dir/textures/ui/voice_on.mat +++ /dev/null @@ -1,12 +0,0 @@ -// Vera Visions Material -{ - noPicMip - noMipmaps - - diffusemap "textures/ui/voice_on.tga" - { - program sprite - map $diffusemap - blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - } -} diff --git a/base/src/Makefile b/base/src/Makefile index c29bd0ae..6fd48572 100644 --- a/base/src/Makefile +++ b/base/src/Makefile @@ -4,3 +4,4 @@ all: cd client && $(MAKE) cd server && $(MAKE) cd menu && $(MAKE) + cd rules && $(MAKE) diff --git a/base/src/client/Makefile b/base/src/client/Makefile index 2fe44a45..24c4e84a 100644 --- a/base/src/client/Makefile +++ b/base/src/client/Makefile @@ -2,3 +2,4 @@ QCC=fteqcc all: $(QCC) progs.src + $(QCC) hud.qc diff --git a/base/src/client/hud.qc b/base/src/client/hud.qc new file mode 100644 index 00000000..6e08af56 --- /dev/null +++ b/base/src/client/hud.qc @@ -0,0 +1,56 @@ +#pragma PROGS_DAT "../../progs.pk3dir/hud.dat" + +#include "../../../src/client/api.h" + +const float baseIconSize = 32.0; +const float baseIconPadding = 16.0; + +font_s FONT_HUD; +var string g_ammoPic; + +void +HUD_Init(void) +{ + font.Load("fonts/font16.font", FONT_HUD); + g_ammoPic = 0; +} + +void +HUD_Draw(vector hud_mins, vector hud_size) +{ + vector hudSize = hud_size; + vector iconPos = hud_mins + (hudSize / 2); + iconPos[1] = (hudSize[1] - baseIconSize) - baseIconPadding; + + string healthValue = ftos(player.GetHealth()); + string armorValue = ftos(player.GetArmor()); + string ammoValue = ftos(weapon.GetAmmo1()); + + /* ammo */ + if (weapon.AmmoRequired() == true) { + draw.RText([hudSize[0] - baseIconPadding - baseIconSize - baseIconPadding, iconPos[1]], ammoValue, FONT_HUD); + } + + if (g_ammoPic != "") { + draw.Pic([hudSize[0] - baseIconPadding - baseIconSize, iconPos[1]], g_ammoPic, [baseIconSize, baseIconSize], [1,1,1], 1.0f); + } + + /* health, armor icons */ + draw.RText(iconPos + [-((baseIconSize/2) + (baseIconPadding/2)) - baseIconPadding, 0], healthValue, FONT_HUD); + draw.Pic(iconPos + [-((baseIconSize/2) + (baseIconPadding/2)), 0], "gfx/hud/health", [baseIconSize, baseIconSize], [1,1,1], 1.0f); + + draw.Text(iconPos + [(baseIconSize/2) + (baseIconPadding/2) + baseIconSize + baseIconPadding, 0], armorValue, FONT_HUD); + draw.Pic(iconPos + [(baseIconSize/2) + (baseIconPadding/2), 0], "gfx/hud/armor", [baseIconSize, baseIconSize], [1,1,1], 1.0f); +} + +void +HUD_DrawSpectator(vector hud_mins, vector hud_size) +{ + +} + +void +HUD_WeaponSwitched(string weaponName) +{ + g_ammoPic = entityDef.GetString(weaponName, "ammoIcon"); +} diff --git a/base/src/client/main.qc b/base/src/client/main.qc index a1c2f057..62c8e4de 100644 --- a/base/src/client/main.qc +++ b/base/src/client/main.qc @@ -127,45 +127,6 @@ ClientGame_EventParse(float fHeader) return (1); } -const float baseIconSize = 32.0; -const float baseIconPadding = 16.0; - -void -HUD_Init(void) -{ -} - -void -HUD_Draw(void) -{ - NSClientPlayer pl = (NSClientPlayer)pSeat->m_ePlayer; - vector hudSize = g_view.GetHUDCanvasSize(); - vector iconPos = g_view.GetHUDCanvasPos() + (hudSize / 2); - iconPos[1] = (hudSize[1] - baseIconSize) - baseIconPadding; - - string healthValue = ftos(pl.health); - string armorValue = ftos(pl.armor); - - /* health, armor icons */ - Font_DrawRText(iconPos + [-((baseIconSize/2) + (baseIconPadding/2)) - baseIconPadding, 0], healthValue, FONT_16); - drawpic(iconPos + [-((baseIconSize/2) + (baseIconPadding/2)), 0], "gfx/hud/health", [baseIconSize, baseIconSize], [1,1,1], 1.0f); - Font_DrawText(iconPos + [(baseIconSize/2) + (baseIconPadding/2) + baseIconSize + baseIconPadding, 0], armorValue, FONT_16); - drawpic(iconPos + [(baseIconSize/2) + (baseIconPadding/2), 0], "gfx/hud/armor", [baseIconSize, baseIconSize], [1,1,1], 1.0f); - - /* little point in not drawing these, even if you don't have a suit */ - if (pl.m_activeWeapon) { - pl.m_activeWeapon.UpdateGUI(); - } - - Textmenu_Draw(); -} - -void -HUD_DrawSpectator(void) -{ - -} - void ClientGame_Init(float apilevel, string enginename, float engineversion) { diff --git a/base/src/progs.src b/base/src/progs.src index e7760ac7..9801e913 100644 --- a/base/src/progs.src +++ b/base/src/progs.src @@ -1,3 +1,5 @@ #pragma sourcefile client/progs.src #pragma sourcefile server/progs.src #pragma sourcefile menu/progs.src +#pragma sourcefile rules/deathmatch.qc +#pragma sourcefile rules/singleplayer.qc diff --git a/base/src/rules/Makefile b/base/src/rules/Makefile new file mode 100644 index 00000000..3e33c696 --- /dev/null +++ b/base/src/rules/Makefile @@ -0,0 +1,6 @@ +QCC=fteqcc + +all: + mkdir -pv ../../progs.pk3dir/progs/ + $(QCC) deathmatch.qc + $(QCC) singleplayer.qc diff --git a/base/src/rules/deathmatch.qc b/base/src/rules/deathmatch.qc new file mode 100644 index 00000000..e49b674e --- /dev/null +++ b/base/src/rules/deathmatch.qc @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024 Marco Cawthorne + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#pragma PROGS_DAT "../../progs.pk3dir/progs/deathmatch.dat" + +#include "../../../src/server/api.h" + +void +CodeCallback_StartGameType(void) +{ + motd.LoadDefault(); +} + +void +CodeCallback_PlayerSpawn(void) +{ + ents.ChangeToClass(self, "player_mp"); + game.TeleportToSpawn(self); +} + +void +CodeCallback_PlayerDisconnect(void) +{ + +} + +bool +CodeCallback_PlayerRequestRespawn(void) +{ + CodeCallback_PlayerSpawn(); + return (true); +} + +void +CodeCallback_PlayerDamage(entity inflictor, entity attacker) +{ + +} + +void +CodeCallback_PlayerKilled(entity inflictor, entity attacker, string weapon) +{ + combat.Obituary(self.netname, attacker.netname, weapon, ""); + + /* death-counter */ + self.deaths++; + + /* update score-counter */ + if (ents.isPlayer(attacker)) { + if (self == attacker) { + attacker.frags--; + } else { + attacker.frags++; + } + } +} diff --git a/base/src/rules/singleplayer.qc b/base/src/rules/singleplayer.qc new file mode 100644 index 00000000..ebd07731 --- /dev/null +++ b/base/src/rules/singleplayer.qc @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2024 Marco Cawthorne + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#pragma PROGS_DAT "../../progs.pk3dir/progs/singleplayer.dat" + +#include "../../../src/server/api.h" + +void +CodeCallback_StartGameType(void) +{ +} + +void +CodeCallback_PlayerSpawn(void) +{ + ents.ChangeToClass(self, "player"); + game.TeleportToSpawn(self); +} + +bool +CodeCallback_PlayerRequestRespawn(void) +{ + localcmd("load quick\n"); + return (true); +} + + +bool +CodeCallback_ImpulseCommand(float impulseNum) +{ + switch (impulseNum) { + case 100: + ents.Input(self, "UseItem", "item_suit", self); + break; + case 101: + ents.Input(self, "SetHealth", "100", self); + ents.Input(self, "SetArmor", "100", self); + ents.Input(self, "GiveItem", "item_suit", self); + ents.Input(self, "GiveItem", "weapon_357", self); + ents.Input(self, "GiveItem", "weapon_9mmAR", self); + ents.Input(self, "GiveItem", "weapon_9mmhandgun", self); + ents.Input(self, "GiveItem", "weapon_crossbow", self); + ents.Input(self, "GiveItem", "weapon_crowbar", self); + ents.Input(self, "GiveItem", "weapon_egon", self); + ents.Input(self, "GiveItem", "weapon_gauss", self); + ents.Input(self, "GiveItem", "weapon_handgrenade", self); + ents.Input(self, "GiveItem", "weapon_hornetgun", self); + ents.Input(self, "GiveItem", "weapon_rpg", self); + ents.Input(self, "GiveItem", "weapon_satchel", self); + ents.Input(self, "GiveItem", "weapon_shotgun", self); + ents.Input(self, "GiveItem", "weapon_snark", self); + ents.Input(self, "GiveItem", "weapon_tripmine", self); + ents.Input(self, "GiveAmmo", "ammo_9mm 255", self); + ents.Input(self, "GiveAmmo", "ammo_357 255", self); + ents.Input(self, "GiveAmmo", "ammo_buckshot 255", self); + ents.Input(self, "GiveAmmo", "ammo_bolt 255", self); + ents.Input(self, "GiveAmmo", "ammo_rocket 255", self); + ents.Input(self, "GiveAmmo", "ammo_uranium 255", self); + ents.Input(self, "GiveAmmo", "ammo_handgrenade 255", self); + ents.Input(self, "GiveAmmo", "ammo_satchel 255", self); + ents.Input(self, "GiveAmmo", "ammo_tripmine 255", self); + ents.Input(self, "GiveAmmo", "ammo_snark 255", self); + ents.Input(self, "GiveAmmo", "ammo_hornet 255", self); + ents.Input(self, "GiveAmmo", "ammo_m203_grenade 255", self); + break; + default: + return (false); + } + + return (true); +} diff --git a/base/src/server/main.qc b/base/src/server/main.qc index edbb2712..a8606274 100644 --- a/base/src/server/main.qc +++ b/base/src/server/main.qc @@ -7,5 +7,9 @@ Game_Worldspawn(void) void Game_InitRules(void) { - g_grMode = NSGameRules::InitFromProgs("maps/mp/gametypes/dm.dat"); + if (cvar("sv_playerslots") == 1 || cvar("coop") == 1) { + g_grMode = NSGameRules::InitFromProgs("progs/singleplayer.dat"); + } else { + g_grMode = NSGameRules::InitFromProgs("progs/deathmatch.dat"); + } } diff --git a/base/test_maps.pk3dir/maps/test/func_chargers.bak b/base/test_maps.pk3dir/maps/test/func_chargers.bak deleted file mode 100644 index 5517d080..00000000 --- a/base/test_maps.pk3dir/maps/test/func_chargers.bak +++ /dev/null @@ -1,137 +0,0 @@ - -// entity 0 -{ -"classname" "worldspawn" -// brush 0 -{ -( 248 192 -64 ) ( 248 -192 -64 ) ( -264 192 -64 ) measure/floor [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( 256 192 8 ) ( -256 192 8 ) ( 256 192 0 ) measure/floor [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( 256 192 8 ) ( 256 192 0 ) ( 256 -192 8 ) measure/floor [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -256 -192 -128 ) ( 256 -192 -128 ) ( -256 192 -128 ) measure/floor [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( -256 -192 0 ) ( -256 -192 8 ) ( 256 -192 0 ) measure/floor [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -256 -192 0 ) ( -256 192 0 ) ( -256 -192 8 ) measure/floor [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -} -// brush 1 -{ -( 248 192 192 ) ( 248 -192 192 ) ( -264 192 192 ) measure/ceiling [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 -0.5 0.5 0 0 0 -( 256 192 264 ) ( -256 192 264 ) ( 256 192 256 ) measure/ceiling [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 -0.5 0.5 0 0 0 -( 256 192 264 ) ( 256 192 256 ) ( 256 -192 264 ) measure/ceiling [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 -0.5 0.5 0 0 0 -( -256 -192 128 ) ( 256 -192 128 ) ( -256 192 128 ) measure/ceiling [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 -0.5 0.5 0 0 0 -( -256 -192 256 ) ( -256 -192 264 ) ( 256 -192 256 ) measure/ceiling [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 -0.5 0.5 0 0 0 -( -256 -192 256 ) ( -256 192 256 ) ( -256 -192 264 ) measure/ceiling [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 -0.5 0.5 0 0 0 -} -// brush 2 -{ -( 192 192 328 ) ( -320 192 328 ) ( 192 192 320 ) measure/wall128gr [ 1 0 0 -128 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -256 192 72 ) ( -256 192 64 ) ( -256 -192 72 ) measure/wall128gr [ 0 1 0 -128 ] [ -0 -0 -1 -128 ] -0 0.5 0.5 0 0 0 -( -768 -192 -64 ) ( -256 -192 -64 ) ( -768 192 -64 ) measure/wall128gr [ 1 0 0 -128 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( -320 -192 320 ) ( -320 -192 328 ) ( 192 -192 320 ) measure/wall128gr [ 1 0 0 -128 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -320 -192 320 ) ( -320 192 320 ) ( -320 -192 328 ) measure/wall128gr [ 0 1 0 -128 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -64 -24 64 ) ( -64 64 64 ) ( 64 -24 64 ) common/caulk [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -} -// brush 3 -{ -( 768 192 328 ) ( 256 192 328 ) ( 768 192 320 ) measure/wall128gr [ 1 0 0 -128 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( 320 192 72 ) ( 320 192 64 ) ( 320 -192 72 ) measure/wall128gr [ 0 1 0 -128 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -192 -192 -64 ) ( 320 -192 -64 ) ( -192 192 -64 ) measure/wall128gr [ 1 0 0 -128 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( 256 -192 320 ) ( 256 -192 328 ) ( 768 -192 320 ) measure/wall128gr [ 1 0 0 -128 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( 256 -192 320 ) ( 256 192 320 ) ( 256 -192 328 ) measure/wall128gr [ 0 1 0 -128 ] [ -0 -0 -1 -128 ] -0 0.5 0.5 0 0 0 -( -64 -24 64 ) ( -64 64 64 ) ( 64 -24 64 ) common/caulk [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -} -// brush 4 -{ -( 192 -192 328 ) ( -320 -192 328 ) ( 192 -192 320 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -0 -1 -128 ] -0 0.5 0.5 0 0 0 -( 320 96 72 ) ( 320 96 64 ) ( 320 -288 72 ) measure/wall128gr [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -768 -576 -64 ) ( -256 -576 -64 ) ( -768 -192 -64 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( 272 -256 320 ) ( 272 -256 328 ) ( 784 -256 320 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -320 -576 320 ) ( -320 -192 320 ) ( -320 -576 328 ) measure/wall128gr [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -64 -24 64 ) ( -64 64 64 ) ( 64 -24 64 ) common/caulk [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -} -// brush 5 -{ -( 192 256 328 ) ( -320 256 328 ) ( 192 256 320 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( 320 544 72 ) ( 320 544 64 ) ( 320 160 72 ) measure/wall128gr [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -768 -128 -64 ) ( -256 -128 -64 ) ( -768 256 -64 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( 272 192 320 ) ( 272 192 328 ) ( 784 192 320 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -0 -1 -128 ] -0 0.5 0.5 0 0 0 -( -320 -128 320 ) ( -320 256 320 ) ( -320 -128 328 ) measure/wall128gr [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -64 -24 64 ) ( -64 64 64 ) ( 64 -24 64 ) common/caulk [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -} -// brush 6 -{ -( 192 192 456 ) ( -320 192 456 ) ( 192 192 448 ) measure/wall64a [ 1 0 0 128 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -256 192 200 ) ( -256 192 192 ) ( -256 -192 200 ) measure/wall64a [ 0 1 0 128 ] [ -0 -0 -1 128 ] -0 0.5 0.5 0 0 0 -( -768 -192 64 ) ( -256 -192 64 ) ( -768 192 64 ) measure/wall64a [ 1 0 0 128 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( -320 -192 448 ) ( -320 -192 456 ) ( 192 -192 448 ) measure/wall64a [ 1 0 0 128 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -320 -192 448 ) ( -320 192 448 ) ( -320 -192 456 ) measure/wall64a [ 0 1 0 128 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -64 -24 192 ) ( -64 64 192 ) ( 64 -24 192 ) measure/wall64a [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -} -// brush 7 -{ -( 768 192 456 ) ( 256 192 456 ) ( 768 192 448 ) measure/wall64a [ 1 0 0 128 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( 320 192 200 ) ( 320 192 192 ) ( 320 -192 200 ) measure/wall64a [ 0 1 0 128 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -192 -192 64 ) ( 320 -192 64 ) ( -192 192 64 ) measure/wall64a [ 1 0 0 128 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( 256 -192 448 ) ( 256 -192 456 ) ( 768 -192 448 ) measure/wall64a [ 1 0 0 128 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( 256 -192 448 ) ( 256 192 448 ) ( 256 -192 456 ) measure/wall64a [ 0 1 0 128 ] [ -0 -0 -1 128 ] -0 0.5 0.5 0 0 0 -( -64 -24 192 ) ( -64 64 192 ) ( 64 -24 192 ) measure/wall64a [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -} -// brush 8 -{ -( 192 -192 456 ) ( -320 -192 456 ) ( 192 -192 448 ) measure/wall64a [ 1 0 0 0 ] [ -0 -0 -1 128 ] -0 0.5 0.5 0 0 0 -( 320 96 200 ) ( 320 96 192 ) ( 320 -288 200 ) measure/wall64a [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -768 -576 64 ) ( -256 -576 64 ) ( -768 -192 64 ) measure/wall64a [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( 272 -256 448 ) ( 272 -256 456 ) ( 784 -256 448 ) measure/wall64a [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -320 -576 448 ) ( -320 -192 448 ) ( -320 -576 456 ) measure/wall64a [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -64 -24 192 ) ( -64 64 192 ) ( 64 -24 192 ) measure/wall64a [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -} -// brush 9 -{ -( 192 256 456 ) ( -320 256 456 ) ( 192 256 448 ) measure/wall64a [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( 320 544 200 ) ( 320 544 192 ) ( 320 160 200 ) measure/wall64a [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -768 -128 64 ) ( -256 -128 64 ) ( -768 256 64 ) measure/wall64a [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( 272 192 448 ) ( 272 192 456 ) ( 784 192 448 ) measure/wall64a [ 1 0 0 0 ] [ -0 -0 -1 128 ] -0 0.5 0.5 0 0 0 -( -320 -128 448 ) ( -320 256 448 ) ( -320 -128 456 ) measure/wall64a [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -64 -24 192 ) ( -64 64 192 ) ( 64 -24 192 ) measure/wall64a [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -} -} -// entity 1 -{ -"classname" "info_player_start" -"origin" "0.000000 0.000000 -24.000000" -} -// entity 2 -{ -"classname" "info_player_deathmatch" -"origin" "0.000000 0.000000 -24.000000" -} -// entity 3 -{ -"classname" "light" -"origin" "0.000000 0.000000 96.000000" -"light" "500" -} -// entity 4 -{ -"classname" "func_healthcharger" -// brush 0 -{ -( 240 136 32 ) ( 240 72 32 ) ( 224 136 32 ) measure/wall64a [ 0 1 0 64 ] [ 1 0 0 0 ] -0 0.5 0.5 0 0 0 -( 256 120 16 ) ( 240 120 16 ) ( 256 120 0 ) measure/wall64a [ -1 0 0 0 ] [ 0 0 -1 0 ] -0 0.5 0.5 0 0 0 -( 256 136 16 ) ( 256 136 0 ) ( 256 72 16 ) measure/wall64a [ 0 1 0 64 ] [ 0 0 -1 0 ] -0 0.5 0.5 0 0 0 -( 240 72 -32 ) ( 256 72 -32 ) ( 240 136 -32 ) measure/wall64a [ 0 1 0 64 ] [ -1 0 0 0 ] -0 0.5 0.5 0 0 0 -( 240 72 0 ) ( 240 72 16 ) ( 256 72 0 ) measure/wall64a [ 1 0 0 0 ] [ 0 0 -1 0 ] -0 0.5 0.5 0 0 0 -( 240 72 -32 ) ( 240 136 -32 ) ( 240 72 -16 ) measure/healthcharge [ 0 -1 0 112 ] [ -0 0 -1 64 ] -0 0.5 0.5 0 0 0 -} -} -// entity 5 -{ -"classname" "func_recharge" -// brush 0 -{ -( 240 -56 32 ) ( 240 -120 32 ) ( 224 -56 32 ) measure/wall64a [ 0 1 0 64 ] [ 1 0 0 0 ] -0 0.5 0.5 0 0 0 -( 256 -72 16 ) ( 240 -72 16 ) ( 256 -72 0 ) measure/wall64a [ -1 0 0 0 ] [ 0 0 -1 0 ] -0 0.5 0.5 0 0 0 -( 256 -56 16 ) ( 256 -56 0 ) ( 256 -120 16 ) measure/wall64a [ 0 1 0 64 ] [ 0 0 -1 0 ] -0 0.5 0.5 0 0 0 -( 240 -120 -32 ) ( 256 -120 -32 ) ( 240 -56 -32 ) measure/wall64a [ 0 1 0 64 ] [ -1 0 0 0 ] -0 0.5 0.5 0 0 0 -( 240 -120 0 ) ( 240 -120 16 ) ( 256 -120 0 ) measure/wall64a [ 1 0 0 0 ] [ 0 0 -1 0 ] -0 0.5 0.5 0 0 0 -( 240 -120 -32 ) ( 240 -56 -32 ) ( 240 -120 -16 ) measure/recharge [ 0 -1 0 112 ] [ -0 0 -1 64 ] -0 0.5 0.5 0 0 0 -} -} diff --git a/base/test_maps.pk3dir/maps/test/func_chargers.prt b/base/test_maps.pk3dir/maps/test/func_chargers.prt deleted file mode 100644 index 4d2fec3c..00000000 --- a/base/test_maps.pk3dir/maps/test/func_chargers.prt +++ /dev/null @@ -1,40 +0,0 @@ -PRT1 -8 -12 -24 -4 0 4 0 (0 0 0 ) (0 0 128 ) (0 192 128 ) (0 192 0 ) -4 0 2 0 (0 0 128 ) (0 0 0 ) (256 0 0 ) (256 0 128 ) -4 0 1 0 (256 0 0 ) (0 0 0 ) (0 192 0 ) (256 192 0 ) -4 1 5 0 (0 0 -64 ) (0 0 0 ) (0 192 0 ) (0 192 -64 ) -4 1 3 0 (0 0 0 ) (0 0 -64 ) (256 0 -64 ) (256 0 0 ) -4 2 6 0 (0 0 128 ) (0 0 0 ) (0 -192 0 ) (0 -192 128 ) -4 2 3 0 (0 -192 0 ) (0 0 0 ) (256 0 0 ) (256 -192 0 ) -4 3 7 0 (0 -192 -64 ) (0 -192 0 ) (0 0 0 ) (0 0 -64 ) -4 4 6 0 (-256 0 0 ) (0 0 0 ) (0 0 128 ) (-256 0 128 ) -4 4 5 0 (0 0 0 ) (-256 0 0 ) (-256 192 0 ) (0 192 0 ) -4 5 7 0 (-256 0 -64 ) (0 0 -64 ) (0 0 0 ) (-256 0 0 ) -4 6 7 0 (-256 0 0 ) (0 0 0 ) (0 -192 0 ) (-256 -192 0 ) -4 0 (256 0 128 ) (256 0 0 ) (256 192 0 ) (256 192 128 ) -4 0 (256 192 128 ) (256 192 0 ) (0 192 0 ) (0 192 128 ) -4 0 (0 0 128 ) (256 0 128 ) (256 192 128 ) (0 192 128 ) -4 1 (256 0 -64 ) (0 0 -64 ) (0 192 -64 ) (256 192 -64 ) -4 1 (256 192 -64 ) (0 192 -64 ) (0 192 0 ) (256 192 0 ) -4 1 (256 0 0 ) (256 0 -64 ) (256 192 -64 ) (256 192 0 ) -4 2 (256 -192 128 ) (256 -192 0 ) (256 0 0 ) (256 0 128 ) -4 2 (0 -192 128 ) (0 -192 0 ) (256 -192 0 ) (256 -192 128 ) -4 2 (0 -192 128 ) (256 -192 128 ) (256 0 128 ) (0 0 128 ) -4 3 (256 -192 -64 ) (0 -192 -64 ) (0 0 -64 ) (256 0 -64 ) -4 3 (256 -192 0 ) (0 -192 0 ) (0 -192 -64 ) (256 -192 -64 ) -4 3 (256 0 0 ) (256 -192 0 ) (256 -192 -64 ) (256 0 -64 ) -4 4 (-256 192 128 ) (-256 192 0 ) (-256 0 0 ) (-256 0 128 ) -4 4 (-256 192 128 ) (0 192 128 ) (0 192 0 ) (-256 192 0 ) -4 4 (0 192 128 ) (-256 192 128 ) (-256 0 128 ) (0 0 128 ) -4 5 (0 0 -64 ) (-256 0 -64 ) (-256 192 -64 ) (0 192 -64 ) -4 5 (-256 192 -64 ) (-256 192 0 ) (0 192 0 ) (0 192 -64 ) -4 5 (-256 192 0 ) (-256 192 -64 ) (-256 0 -64 ) (-256 0 0 ) -4 6 (-256 0 128 ) (-256 0 0 ) (-256 -192 0 ) (-256 -192 128 ) -4 6 (-256 -192 0 ) (0 -192 0 ) (0 -192 128 ) (-256 -192 128 ) -4 6 (0 0 128 ) (-256 0 128 ) (-256 -192 128 ) (0 -192 128 ) -4 7 (0 -192 -64 ) (-256 -192 -64 ) (-256 0 -64 ) (0 0 -64 ) -4 7 (0 -192 -64 ) (0 -192 0 ) (-256 -192 0 ) (-256 -192 -64 ) -4 7 (-256 0 -64 ) (-256 -192 -64 ) (-256 -192 0 ) (-256 0 0 ) diff --git a/base/test_maps.pk3dir/maps/test/func_chargers.srf b/base/test_maps.pk3dir/maps/test/func_chargers.srf deleted file mode 100644 index 4e196d8c..00000000 --- a/base/test_maps.pk3dir/maps/test/func_chargers.srf +++ /dev/null @@ -1,164 +0,0 @@ -default -{ - castShadows 1 - receiveShadows 1 - sampleSize 16 - longestCurve 0.000000 -} - -0 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall64a - lightmapAxis ( 0.000000 -1.000000 0.000000 ) -} - -1 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall64a - lightmapAxis ( 0.000000 1.000000 0.000000 ) -} - -2 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall64a - lightmapAxis ( -1.000000 0.000000 0.000000 ) -} - -3 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall64a - lightmapAxis ( 1.000000 0.000000 0.000000 ) -} - -4 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall128gr - lightmapAxis ( 0.000000 -1.000000 0.000000 ) -} - -5 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall128gr - lightmapAxis ( 0.000000 1.000000 0.000000 ) -} - -6 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall128gr - lightmapAxis ( -1.000000 0.000000 0.000000 ) -} - -7 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall128gr - lightmapAxis ( 1.000000 0.000000 0.000000 ) -} - -8 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/ceiling - lightmapAxis ( 0.000000 0.000000 -1.000000 ) -} - -9 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/floor - lightmapAxis ( 0.000000 0.000000 1.000000 ) -} - -10 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/healthcharge - entity 4 - castShadows 0 - lightmapAxis ( -1.000000 0.000000 0.000000 ) -} - -11 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall64a - entity 4 - castShadows 0 - lightmapAxis ( 1.000000 0.000000 0.000000 ) -} - -12 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall64a - entity 4 - castShadows 0 - lightmapAxis ( 0.000000 -1.000000 0.000000 ) -} - -13 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall64a - entity 4 - castShadows 0 - lightmapAxis ( 0.000000 1.000000 0.000000 ) -} - -14 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall64a - entity 4 - castShadows 0 - lightmapAxis ( 0.000000 0.000000 -1.000000 ) -} - -15 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall64a - entity 4 - castShadows 0 - lightmapAxis ( 0.000000 0.000000 1.000000 ) -} - -16 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/recharge - entity 5 - castShadows 0 - lightmapAxis ( -1.000000 0.000000 0.000000 ) -} - -17 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall64a - entity 5 - castShadows 0 - lightmapAxis ( 1.000000 0.000000 0.000000 ) -} - -18 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall64a - entity 5 - castShadows 0 - lightmapAxis ( 0.000000 -1.000000 0.000000 ) -} - -19 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall64a - entity 5 - castShadows 0 - lightmapAxis ( 0.000000 1.000000 0.000000 ) -} - -20 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall64a - entity 5 - castShadows 0 - lightmapAxis ( 0.000000 0.000000 -1.000000 ) -} - -21 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall64a - entity 5 - castShadows 0 - lightmapAxis ( 0.000000 0.000000 1.000000 ) -} - diff --git a/base/test_maps.pk3dir/maps/test/mapscript.bak b/base/test_maps.pk3dir/maps/test/mapscript.bak deleted file mode 100644 index 4de79d6a..00000000 --- a/base/test_maps.pk3dir/maps/test/mapscript.bak +++ /dev/null @@ -1,115 +0,0 @@ - -// entity 0 -{ -"classname" "worldspawn" -"sun_pos" "44.5842 325.561 0" -"lf_pos" "315.416 145.561 0" -// brush 0 -{ -( 512 512 0 ) ( 512 -512 0 ) ( -512 512 0 ) next/bunker3 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 -( 512 512 0 ) ( -512 512 0 ) ( 512 512 -128 ) next/bunker3 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 -( 512 512 0 ) ( 512 512 -128 ) ( 512 -512 0 ) next/bunker3 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 -( -512 -512 -128 ) ( 512 -512 -128 ) ( -512 512 -128 ) next/bunker3 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 -( -512 -512 -128 ) ( -512 -512 0 ) ( 512 -512 -128 ) next/bunker3 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 -( -512 -512 -128 ) ( -512 512 -128 ) ( -512 -512 0 ) next/bunker3 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 -} -// brush 1 -{ -( -512 640 256 ) ( -512 -640 256 ) ( -640 640 256 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( -512 640 128 ) ( -640 640 128 ) ( -512 640 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -512 640 128 ) ( -512 640 0 ) ( -512 -640 128 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -640 -640 0 ) ( -512 -640 0 ) ( -640 640 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( -640 -640 0 ) ( -640 -640 128 ) ( -512 -640 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -640 -640 0 ) ( -640 640 0 ) ( -640 -640 128 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -} -// brush 2 -{ -( 640 640 256 ) ( 640 512 256 ) ( -512 640 256 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( 640 640 256 ) ( -512 640 256 ) ( 640 640 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( 640 640 256 ) ( 640 640 0 ) ( 640 512 256 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -512 512 0 ) ( 640 512 0 ) ( -512 640 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( -512 512 0 ) ( -512 512 256 ) ( 640 512 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -512 512 0 ) ( -512 640 0 ) ( -512 512 256 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -} -// brush 3 -{ -( 640 512 256 ) ( 640 -640 256 ) ( 512 512 256 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( 640 512 256 ) ( 512 512 256 ) ( 640 512 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( 640 512 256 ) ( 640 512 0 ) ( 640 -640 256 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( 512 -640 0 ) ( 640 -640 0 ) ( 512 512 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( 512 -640 0 ) ( 512 -640 256 ) ( 640 -640 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( 512 -640 0 ) ( 512 512 0 ) ( 512 -640 256 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -} -// brush 4 -{ -( 512 -512 256 ) ( 512 -640 256 ) ( -512 -512 256 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( 512 -512 256 ) ( -512 -512 256 ) ( 512 -512 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( 512 -512 256 ) ( 512 -512 0 ) ( 512 -640 256 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -512 -640 0 ) ( 512 -640 0 ) ( -512 -512 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( -512 -640 0 ) ( -512 -640 256 ) ( 512 -640 0 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -512 -640 0 ) ( -512 -512 0 ) ( -512 -640 256 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -} -// brush 5 -{ -( 512 512 384 ) ( 512 -512 384 ) ( -512 512 384 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( 512 512 512 ) ( -512 512 512 ) ( 512 512 256 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( 512 512 512 ) ( 512 512 256 ) ( 512 -512 512 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -512 -512 256 ) ( 512 -512 256 ) ( -512 512 256 ) skies/smudge [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( -512 -512 256 ) ( -512 -512 512 ) ( 512 -512 256 ) skies/smudge [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -512 -512 256 ) ( -512 512 256 ) ( -512 -512 512 ) skies/smudge [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -} -// brush 6 -{ -( -128 192 64 ) ( -128 64 64 ) ( -256 192 64 ) next/bunker8 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 -( -128 192 64 ) ( -256 192 64 ) ( -128 192 -64 ) next/bunker8 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 -( -192 256 124 ) ( -192 256 -4 ) ( -192 128 124 ) next/bunker8 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 -( -256 128 0 ) ( -128 128 0 ) ( -256 256 0 ) next/bunker8 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 -( -256 128 0 ) ( -256 128 128 ) ( -128 128 0 ) next/bunker8 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 -( -256 128 0 ) ( -256 256 0 ) ( -256 128 128 ) next/bunker8 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 -} -// brush 7 -{ -( 384 320 128 ) ( 384 192 128 ) ( 256 320 128 ) next/bunker8 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 -( 384 320 64 ) ( 256 320 64 ) ( 384 320 -64 ) next/bunker8 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 -( 320 384 124 ) ( 320 384 -4 ) ( 320 256 124 ) next/bunker8 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 -( 256 256 0 ) ( 384 256 0 ) ( 256 384 0 ) next/bunker8 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 -( 256 256 0 ) ( 256 256 128 ) ( 384 256 0 ) next/bunker8 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 -( 256 256 0 ) ( 256 384 0 ) ( 256 256 128 ) next/bunker8 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 -} -// brush 8 -{ -( 320 -192 128 ) ( 320 -320 128 ) ( 192 -192 128 ) next/bunker8 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 -( 320 -192 64 ) ( 192 -192 64 ) ( 320 -192 -64 ) next/bunker8 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 -( 256 -128 124 ) ( 256 -128 -4 ) ( 256 -256 124 ) next/bunker8 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 -( 192 -256 0 ) ( 320 -256 0 ) ( 192 -128 0 ) next/bunker8 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 -( 192 -256 0 ) ( 192 -256 128 ) ( 320 -256 0 ) next/bunker8 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 -( 192 -256 0 ) ( 192 -128 0 ) ( 192 -256 128 ) next/bunker8 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 -} -// brush 9 -{ -( -128 -256 64 ) ( -128 -384 64 ) ( -256 -256 64 ) next/bunker8 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 -( -128 -256 64 ) ( -256 -256 64 ) ( -128 -256 -64 ) next/bunker8 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 -( -192 -192 124 ) ( -192 -192 -4 ) ( -192 -320 124 ) next/bunker8 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 -( -256 -320 0 ) ( -128 -320 0 ) ( -256 -192 0 ) next/bunker8 [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.25 0.25 0 0 0 -( -256 -320 0 ) ( -256 -320 128 ) ( -128 -320 0 ) next/bunker8 [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 -( -256 -320 0 ) ( -256 -192 0 ) ( -256 -320 128 ) next/bunker8 [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.25 0.25 0 0 0 -} -} -// entity 1 -{ -"classname" "light_environment" -"origin" "0 0 192" -"color" "0.996 0.941 0.835" -"ambientcolor" "0.678 0.816 0.949" -"intensity" "250" -"sunangle" "-44.616" -"pitch" "-145.86" -"filterradius" "1" -"sunspreadangle" "0" -"samples" "16" -} -// entity 2 -{ -"classname" "point_message" -"origin" "0 0 64" -} diff --git a/base/test_maps.pk3dir/maps/test/mapscript.prt b/base/test_maps.pk3dir/maps/test/mapscript.prt deleted file mode 100644 index dc202336..00000000 --- a/base/test_maps.pk3dir/maps/test/mapscript.prt +++ /dev/null @@ -1,121 +0,0 @@ -PRT1 -20 -51 -66 -4 0 6 0 (320 0 0 ) (512 0 0 ) (512 0 128 ) (320 0 128 ) -4 0 5 0 (512 0 128 ) (512 0 256 ) (320 0 256 ) (320 0 128 ) -4 0 2 0 (320 512 128 ) (320 512 0 ) (320 320 0 ) (320 320 128 ) -4 0 3 0 (320 256 0 ) (320 0 0 ) (320 0 128 ) (320 256 128 ) -4 0 1 0 (320 512 256 ) (320 512 128 ) (320 0 128 ) (320 0 256 ) -4 1 5 0 (320 0 128 ) (320 0 256 ) (256 0 256 ) (256 0 128 ) -4 1 2 0 (256 320 128 ) (256 512 128 ) (320 512 128 ) (320 320 128 ) -4 1 3 0 (256 0 128 ) (256 256 128 ) (320 256 128 ) (320 0 128 ) -4 1 4 0 (256 512 256 ) (256 512 128 ) (256 0 128 ) (256 0 256 ) -4 2 4 0 (256 512 128 ) (256 512 0 ) (256 320 0 ) (256 320 128 ) -4 3 6 0 (256 0 0 ) (320 0 0 ) (320 0 128 ) (256 0 128 ) -4 3 4 0 (256 256 0 ) (256 0 0 ) (256 0 128 ) (256 256 128 ) -4 4 11 0 (0 512 64 ) (0 512 0 ) (0 128 0 ) (0 128 64 ) -4 4 10 0 (0 128 256 ) (0 512 256 ) (0 512 64 ) (0 128 64 ) -4 4 14 0 (0 0 0 ) (0 0 256 ) (0 128 256 ) (0 128 0 ) -4 4 6 0 (192 0 0 ) (256 0 0 ) (256 0 128 ) (192 0 128 ) -4 4 8 0 (0 0 128 ) (0 0 0 ) (192 0 0 ) (192 0 128 ) -4 4 5 0 (0 0 256 ) (0 0 128 ) (256 0 128 ) (256 0 256 ) -4 5 15 0 (0 -256 256 ) (0 0 256 ) (0 0 128 ) (0 -256 128 ) -4 5 9 0 (512 -256 128 ) (512 -256 256 ) (0 -256 256 ) (0 -256 128 ) -4 5 7 0 (512 -256 128 ) (256 -256 128 ) (256 -192 128 ) (512 -192 128 ) -4 5 6 0 (192 -192 128 ) (192 0 128 ) (512 0 128 ) (512 -192 128 ) -4 5 8 0 (192 -256 128 ) (0 -256 128 ) (0 0 128 ) (192 0 128 ) -4 6 7 0 (256 -192 0 ) (512 -192 0 ) (512 -192 128 ) (256 -192 128 ) -4 6 8 0 (192 0 0 ) (192 -192 0 ) (192 -192 128 ) (192 0 128 ) -4 7 9 0 (256 -256 0 ) (512 -256 0 ) (512 -256 128 ) (256 -256 128 ) -4 8 16 0 (0 0 64 ) (0 0 0 ) (0 -256 0 ) (0 -256 64 ) -4 8 15 0 (0 0 128 ) (0 0 64 ) (0 -256 64 ) (0 -256 128 ) -4 8 9 0 (0 -256 0 ) (192 -256 0 ) (192 -256 128 ) (0 -256 128 ) -4 9 19 0 (0 -512 256 ) (0 -320 256 ) (0 -320 0 ) (0 -512 0 ) -4 9 17 0 (0 -256 64 ) (0 -256 0 ) (0 -320 0 ) (0 -320 64 ) -4 9 15 0 (0 -320 256 ) (0 -256 256 ) (0 -256 64 ) (0 -320 64 ) -4 10 12 0 (-256 192 64 ) (-256 512 64 ) (-192 512 64 ) (-192 192 64 ) -4 10 11 0 (0 128 64 ) (-192 128 64 ) (-192 512 64 ) (0 512 64 ) -4 10 13 0 (-256 512 256 ) (-256 512 64 ) (-256 128 64 ) (-256 128 256 ) -4 10 14 0 (0 128 64 ) (0 128 256 ) (-256 128 256 ) (-256 128 64 ) -4 11 12 0 (-192 192 64 ) (-192 512 64 ) (-192 512 0 ) (-192 192 0 ) -4 11 14 0 (-192 128 0 ) (0 128 0 ) (0 128 64 ) (-192 128 64 ) -4 12 13 0 (-256 512 64 ) (-256 512 0 ) (-256 192 0 ) (-256 192 64 ) -4 13 14 0 (-512 128 256 ) (-512 128 0 ) (-256 128 0 ) (-256 128 256 ) -4 14 16 0 (-256 0 0 ) (0 0 0 ) (0 0 64 ) (-256 0 64 ) -4 14 18 0 (-512 0 0 ) (-256 0 0 ) (-256 0 64 ) (-512 0 64 ) -4 14 15 0 (0 0 64 ) (0 0 256 ) (-512 0 256 ) (-512 0 64 ) -4 15 19 0 (-512 -320 256 ) (-512 -320 64 ) (0 -320 64 ) (0 -320 256 ) -4 15 17 0 (0 -320 64 ) (-192 -320 64 ) (-192 -256 64 ) (0 -256 64 ) -4 15 16 0 (-256 -256 64 ) (-256 0 64 ) (0 0 64 ) (0 -256 64 ) -4 15 18 0 (-256 -320 64 ) (-512 -320 64 ) (-512 0 64 ) (-256 0 64 ) -4 16 17 0 (-192 -256 0 ) (0 -256 0 ) (0 -256 64 ) (-192 -256 64 ) -4 16 18 0 (-256 0 0 ) (-256 -256 0 ) (-256 -256 64 ) (-256 0 64 ) -4 17 19 0 (-192 -320 0 ) (0 -320 0 ) (0 -320 64 ) (-192 -320 64 ) -4 18 19 0 (-512 -320 64 ) (-512 -320 0 ) (-256 -320 0 ) (-256 -320 64 ) -4 0 (320 320 0 ) (320 256 0 ) (320 256 128 ) (320 320 128 ) -4 0 (512 0 256 ) (512 0 0 ) (512 512 0 ) (512 512 256 ) -4 0 (320 512 256 ) (512 512 256 ) (512 512 0 ) (320 512 0 ) -4 0 (512 0 0 ) (320 0 0 ) (320 512 0 ) (512 512 0 ) -4 0 (512 512 256 ) (320 512 256 ) (320 0 256 ) (512 0 256 ) -4 1 (256 256 128 ) (256 320 128 ) (320 320 128 ) (320 256 128 ) -4 1 (320 512 256 ) (256 512 256 ) (256 0 256 ) (320 0 256 ) -4 1 (256 512 128 ) (256 512 256 ) (320 512 256 ) (320 512 128 ) -4 2 (256 320 0 ) (256 512 0 ) (320 512 0 ) (320 320 0 ) -4 2 (256 512 128 ) (320 512 128 ) (320 512 0 ) (256 512 0 ) -4 2 (320 320 0 ) (320 320 128 ) (256 320 128 ) (256 320 0 ) -4 3 (256 256 0 ) (256 256 128 ) (320 256 128 ) (320 256 0 ) -4 3 (320 0 0 ) (256 0 0 ) (256 256 0 ) (320 256 0 ) -4 4 (256 320 128 ) (256 256 128 ) (256 256 0 ) (256 320 0 ) -4 4 (0 512 256 ) (256 512 256 ) (256 512 0 ) (0 512 0 ) -4 4 (256 0 0 ) (0 0 0 ) (0 512 0 ) (256 512 0 ) -4 4 (256 512 256 ) (0 512 256 ) (0 0 256 ) (256 0 256 ) -4 5 (256 -256 128 ) (192 -256 128 ) (192 -192 128 ) (256 -192 128 ) -4 5 (512 -256 256 ) (512 0 256 ) (0 0 256 ) (0 -256 256 ) -4 5 (512 0 128 ) (512 0 256 ) (512 -256 256 ) (512 -256 128 ) -4 6 (192 -192 128 ) (192 -192 0 ) (256 -192 0 ) (256 -192 128 ) -4 6 (192 0 0 ) (512 0 0 ) (512 -192 0 ) (192 -192 0 ) -4 6 (512 0 128 ) (512 -192 128 ) (512 -192 0 ) (512 0 0 ) -4 7 (512 -192 128 ) (512 -256 128 ) (512 -256 0 ) (512 -192 0 ) -4 7 (512 -192 0 ) (512 -256 0 ) (256 -256 0 ) (256 -192 0 ) -4 7 (256 -192 128 ) (256 -192 0 ) (256 -256 0 ) (256 -256 128 ) -4 8 (192 -192 128 ) (192 -256 128 ) (192 -256 0 ) (192 -192 0 ) -4 8 (0 -256 0 ) (0 0 0 ) (192 0 0 ) (192 -256 0 ) -4 9 (512 -512 256 ) (512 -256 256 ) (0 -256 256 ) (0 -512 256 ) -4 9 (0 -512 0 ) (0 -256 0 ) (512 -256 0 ) (512 -512 0 ) -4 9 (512 -256 256 ) (512 -512 256 ) (512 -512 0 ) (512 -256 0 ) -4 9 (192 -256 128 ) (256 -256 128 ) (256 -256 0 ) (192 -256 0 ) -4 9 (0 -512 0 ) (512 -512 0 ) (512 -512 256 ) (0 -512 256 ) -4 10 (-192 128 64 ) (-256 128 64 ) (-256 192 64 ) (-192 192 64 ) -4 10 (-256 128 256 ) (0 128 256 ) (0 512 256 ) (-256 512 256 ) -4 10 (-256 512 64 ) (-256 512 256 ) (0 512 256 ) (0 512 64 ) -4 11 (-192 128 0 ) (-192 128 64 ) (-192 192 64 ) (-192 192 0 ) -4 11 (-192 512 64 ) (0 512 64 ) (0 512 0 ) (-192 512 0 ) -4 11 (-192 512 0 ) (0 512 0 ) (0 128 0 ) (-192 128 0 ) -4 12 (-256 512 0 ) (-192 512 0 ) (-192 192 0 ) (-256 192 0 ) -4 12 (-256 512 64 ) (-192 512 64 ) (-192 512 0 ) (-256 512 0 ) -4 12 (-192 192 0 ) (-192 192 64 ) (-256 192 64 ) (-256 192 0 ) -4 13 (-256 192 64 ) (-256 128 64 ) (-256 128 0 ) (-256 192 0 ) -4 13 (-256 512 256 ) (-256 512 0 ) (-512 512 0 ) (-512 512 256 ) -4 13 (-512 512 0 ) (-512 128 0 ) (-512 128 256 ) (-512 512 256 ) -4 13 (-512 128 0 ) (-512 512 0 ) (-256 512 0 ) (-256 128 0 ) -4 13 (-256 128 256 ) (-256 512 256 ) (-512 512 256 ) (-512 128 256 ) -4 14 (-256 128 64 ) (-192 128 64 ) (-192 128 0 ) (-256 128 0 ) -4 14 (-512 128 0 ) (-512 0 0 ) (-512 0 256 ) (-512 128 256 ) -4 14 (0 0 0 ) (-512 0 0 ) (-512 128 0 ) (0 128 0 ) -4 14 (0 128 256 ) (-512 128 256 ) (-512 0 256 ) (0 0 256 ) -4 15 (-192 -320 64 ) (-256 -320 64 ) (-256 -256 64 ) (-192 -256 64 ) -4 15 (-512 -320 256 ) (0 -320 256 ) (0 0 256 ) (-512 0 256 ) -4 15 (-512 -320 64 ) (-512 -320 256 ) (-512 0 256 ) (-512 0 64 ) -4 16 (-256 -256 64 ) (-256 -256 0 ) (-192 -256 0 ) (-192 -256 64 ) -4 16 (-256 0 0 ) (0 0 0 ) (0 -256 0 ) (-256 -256 0 ) -4 17 (0 -256 0 ) (0 -320 0 ) (-192 -320 0 ) (-192 -256 0 ) -4 17 (-192 -256 64 ) (-192 -256 0 ) (-192 -320 0 ) (-192 -320 64 ) -4 18 (-256 -256 64 ) (-256 -320 64 ) (-256 -320 0 ) (-256 -256 0 ) -4 18 (-512 0 0 ) (-512 -320 0 ) (-512 -320 64 ) (-512 0 64 ) -4 18 (-512 0 0 ) (-256 0 0 ) (-256 -320 0 ) (-512 -320 0 ) -4 19 (-512 -320 256 ) (-512 -512 256 ) (0 -512 256 ) (0 -320 256 ) -4 19 (0 -320 0 ) (0 -512 0 ) (-512 -512 0 ) (-512 -320 0 ) -4 19 (-512 -320 0 ) (-512 -512 0 ) (-512 -512 256 ) (-512 -320 256 ) -4 19 (-256 -320 64 ) (-192 -320 64 ) (-192 -320 0 ) (-256 -320 0 ) -4 19 (-512 -512 256 ) (-512 -512 0 ) (0 -512 0 ) (0 -512 256 ) diff --git a/base/test_maps.pk3dir/maps/test/mapscript.mapC b/base/test_maps.pk3dir/maps/test/mapscript.qc similarity index 78% rename from base/test_maps.pk3dir/maps/test/mapscript.mapC rename to base/test_maps.pk3dir/maps/test/mapscript.qc index 7258cc89..c2404b78 100644 --- a/base/test_maps.pk3dir/maps/test/mapscript.mapC +++ b/base/test_maps.pk3dir/maps/test/mapscript.qc @@ -1,6 +1,6 @@ #pragma PROGS_DAT "mapscript.dat" -#include "../../../src/server/mapC.src" +#include "../../../src/server/api.h" void main() { @@ -11,4 +11,9 @@ void main() radio = spawnClass("info_player_deathmatch", [0, 0, 128]); radio.angles = [0, random(-180, 180), 0]; radio.targetname = "MPSpawn"; +} + +void CSEv_TriggerTarget_s(string toTrigger) +{ + } \ No newline at end of file diff --git a/base/test_maps.pk3dir/maps/test/mapscript.srf b/base/test_maps.pk3dir/maps/test/mapscript.srf deleted file mode 100644 index 29f60cd1..00000000 --- a/base/test_maps.pk3dir/maps/test/mapscript.srf +++ /dev/null @@ -1,164 +0,0 @@ -default -{ - castShadows 1 - receiveShadows 1 - sampleSize 16 - longestCurve 0.000000 -} - -0 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/next/bunker8 - lightmapAxis ( -1.000000 0.000000 0.000000 ) -} - -1 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/next/bunker8 - lightmapAxis ( 1.000000 0.000000 0.000000 ) -} - -2 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/next/bunker8 - lightmapAxis ( 0.000000 -1.000000 0.000000 ) -} - -3 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/next/bunker8 - lightmapAxis ( 0.000000 1.000000 0.000000 ) -} - -4 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/next/bunker8 - lightmapAxis ( 0.000000 0.000000 1.000000 ) -} - -5 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/next/bunker8 - lightmapAxis ( -1.000000 0.000000 0.000000 ) -} - -6 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/next/bunker8 - lightmapAxis ( 1.000000 0.000000 0.000000 ) -} - -7 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/next/bunker8 - lightmapAxis ( 0.000000 -1.000000 0.000000 ) -} - -8 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/next/bunker8 - lightmapAxis ( 0.000000 1.000000 0.000000 ) -} - -9 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/next/bunker8 - lightmapAxis ( 0.000000 0.000000 1.000000 ) -} - -10 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/next/bunker8 - lightmapAxis ( -1.000000 0.000000 0.000000 ) -} - -11 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/next/bunker8 - lightmapAxis ( 1.000000 0.000000 0.000000 ) -} - -12 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/next/bunker8 - lightmapAxis ( 0.000000 -1.000000 0.000000 ) -} - -13 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/next/bunker8 - lightmapAxis ( 0.000000 1.000000 0.000000 ) -} - -14 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/next/bunker8 - lightmapAxis ( 0.000000 0.000000 1.000000 ) -} - -15 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/next/bunker8 - lightmapAxis ( -1.000000 0.000000 0.000000 ) -} - -16 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/next/bunker8 - lightmapAxis ( 1.000000 0.000000 0.000000 ) -} - -17 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/next/bunker8 - lightmapAxis ( 0.000000 -1.000000 0.000000 ) -} - -18 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/next/bunker8 - lightmapAxis ( 0.000000 1.000000 0.000000 ) -} - -19 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/next/bunker8 - lightmapAxis ( 0.000000 0.000000 1.000000 ) -} - -20 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/skies/smudge - sampleSize 0 -} - -21 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/skies/smudge - sampleSize 0 -} - -22 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/skies/smudge - sampleSize 0 -} - -23 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/skies/smudge - sampleSize 0 -} - -24 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/skies/smudge - sampleSize 0 -} - -25 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/next/bunker3 - lightmapAxis ( 0.000000 0.000000 1.000000 ) -} - diff --git a/base/test_maps.pk3dir/maps/test/ui.qc b/base/test_maps.pk3dir/maps/test/ui.qc new file mode 100644 index 00000000..fd69b364 --- /dev/null +++ b/base/test_maps.pk3dir/maps/test/ui.qc @@ -0,0 +1,13 @@ +#pragma PROGS_DAT "ui.dat" + +#include "../../../../src/server/api.h" + +void +CSEv_TriggerTarget_s(string toTrigger) +{ + entity findMe = find(world, ::targetname, toTrigger); + + if (findMe) { + sendInput(findMe, "Trigger", "", self); + } +} diff --git a/base/test_maps.pk3dir/maps/test/weapons.bak b/base/test_maps.pk3dir/maps/test/weapons.bak deleted file mode 100644 index c2c2c155..00000000 --- a/base/test_maps.pk3dir/maps/test/weapons.bak +++ /dev/null @@ -1,100 +0,0 @@ - -// entity 0 -{ -"classname" "worldspawn" -// brush 0 -{ -( 248 192 -64 ) ( 248 -192 -64 ) ( -264 192 -64 ) measure/floor [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( 256 192 8 ) ( -256 192 8 ) ( 256 192 0 ) measure/floor [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( 256 192 8 ) ( 256 192 0 ) ( 256 -192 8 ) measure/floor [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -256 -192 -128 ) ( 256 -192 -128 ) ( -256 192 -128 ) measure/floor [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( -256 -192 0 ) ( -256 -192 8 ) ( 256 -192 0 ) measure/floor [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -256 -192 0 ) ( -256 192 0 ) ( -256 -192 8 ) measure/floor [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -} -// brush 1 -{ -( 248 192 192 ) ( 248 -192 192 ) ( -264 192 192 ) measure/floor [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( 256 192 264 ) ( -256 192 264 ) ( 256 192 256 ) measure/floor [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( 256 192 264 ) ( 256 192 256 ) ( 256 -192 264 ) measure/floor [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -256 -192 128 ) ( 256 -192 128 ) ( -256 192 128 ) measure/floor [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( -256 -192 256 ) ( -256 -192 264 ) ( 256 -192 256 ) measure/floor [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -256 -192 256 ) ( -256 192 256 ) ( -256 -192 264 ) measure/floor [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -} -// brush 2 -{ -( 184 192 192 ) ( 184 -192 192 ) ( -328 192 192 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( 192 192 264 ) ( -320 192 264 ) ( 192 192 256 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -256 192 8 ) ( -256 192 0 ) ( -256 -192 8 ) measure/wall128gr [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -768 -192 -128 ) ( -256 -192 -128 ) ( -768 192 -128 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( -320 -192 256 ) ( -320 -192 264 ) ( 192 -192 256 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -320 -192 256 ) ( -320 192 256 ) ( -320 -192 264 ) measure/wall128gr [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -} -// brush 3 -{ -( 760 192 192 ) ( 760 -192 192 ) ( 248 192 192 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( 768 192 264 ) ( 256 192 264 ) ( 768 192 256 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( 320 192 8 ) ( 320 192 0 ) ( 320 -192 8 ) measure/wall128gr [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -192 -192 -128 ) ( 320 -192 -128 ) ( -192 192 -128 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( 256 -192 256 ) ( 256 -192 264 ) ( 768 -192 256 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( 256 -192 256 ) ( 256 192 256 ) ( 256 -192 264 ) measure/wall128gr [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -} -// brush 4 -{ -( 184 -192 192 ) ( 184 -576 192 ) ( -328 -192 192 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( 192 -192 264 ) ( -320 -192 264 ) ( 192 -192 256 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( 320 96 8 ) ( 320 96 0 ) ( 320 -288 8 ) measure/wall128gr [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -768 -576 -128 ) ( -256 -576 -128 ) ( -768 -192 -128 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( 272 -256 256 ) ( 272 -256 264 ) ( 784 -256 256 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -320 -576 256 ) ( -320 -192 256 ) ( -320 -576 264 ) measure/wall128gr [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -} -// brush 5 -{ -( 184 256 192 ) ( 184 -128 192 ) ( -328 256 192 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( 192 256 264 ) ( -320 256 264 ) ( 192 256 256 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( 320 544 8 ) ( 320 544 0 ) ( 320 160 8 ) measure/wall128gr [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -768 -128 -128 ) ( -256 -128 -128 ) ( -768 256 -128 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -1 -0 0 ] -0 0.5 0.5 0 0 0 -( 272 192 256 ) ( 272 192 264 ) ( 784 192 256 ) measure/wall128gr [ 1 0 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -( -320 -128 256 ) ( -320 256 256 ) ( -320 -128 264 ) measure/wall128gr [ 0 1 0 0 ] [ -0 -0 -1 0 ] -0 0.5 0.5 0 0 0 -} -} -// entity 1 -{ -"classname" "info_player_start" -"origin" "0.000000 0.000000 -24.000000" -} -// entity 2 -{ -"classname" "info_player_deathmatch" -"origin" "0.000000 0.000000 -24.000000" -} -// entity 3 -{ -"classname" "light" -"origin" "0.000000 0.000000 96.000000" -"light" "500" -} -// entity 4 -{ -"classname" "env_explosion" -"targetname" "testtrigger" -"origin" "0.000000 0.000000 0.000000" -"iMagnitude" "1024" -} -// entity 5 -{ -"classname" "weapon_bat" -"origin" "-128.000000 0.000000 -8.000000" -"angles" "0 180 0" -} -// entity 6 -{ -"classname" "weapon_pistol" -"origin" "0.000000 -128.000000 -8.000000" -"angles" "0 -90 0" -} -// entity 7 -{ -"classname" "weapon_frag" -"origin" "0.000000 128.000000 -8.000000" -"angles" "0 90 0" -} diff --git a/base/test_maps.pk3dir/maps/test/weapons.srf b/base/test_maps.pk3dir/maps/test/weapons.srf deleted file mode 100644 index ef7fbac7..00000000 --- a/base/test_maps.pk3dir/maps/test/weapons.srf +++ /dev/null @@ -1,44 +0,0 @@ -default -{ - castShadows 1 - receiveShadows 1 - sampleSize 16 - longestCurve 0.000000 -} - -0 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall128gr - lightmapAxis ( 0.000000 -1.000000 0.000000 ) -} - -1 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall128gr - lightmapAxis ( 0.000000 1.000000 0.000000 ) -} - -2 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall128gr - lightmapAxis ( -1.000000 0.000000 0.000000 ) -} - -3 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/wall128gr - lightmapAxis ( 1.000000 0.000000 0.000000 ) -} - -4 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/floor - lightmapAxis ( 0.000000 0.000000 -1.000000 ) -} - -5 // SURFACE_FACE V: 4 I: 6 planar -{ - shader textures/measure/floor - lightmapAxis ( 0.000000 0.000000 1.000000 ) -} - diff --git a/base/test_maps.pk3dir/models/logo.iqm b/base/test_maps.pk3dir/models/logo.iqm new file mode 100644 index 0000000000000000000000000000000000000000..75e16e4d7197a4f76a54fbd78047cb56b43a5bbe GIT binary patch literal 614912 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"ZF01&Z@J~tL|SlG;0jwhX);S|ImAi8RLZ6 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"ZF01 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

  1. rAW&MYU4HR+Xb9$~D>P#?}?O&+KnL3ymn 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 D2KEut literal 0 HcmV?d00001 diff --git a/src/botlib/defs.h b/src/botlib/defs.h index 1a1ea6bf..83f4e51c 100644 --- a/src/botlib/defs.h +++ b/src/botlib/defs.h @@ -14,47 +14,54 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "cvars.h" -#include "profiles.h" - -/** @defgroup bot Bot -@brief Multiplayer game opponents, allies. -@ingroup ai - -# Bot {#bot} - -@{ -*/ - +#include "cvars.h" +#include "profiles.h" + +/** @defgroup bot Bot +@brief Multiplayer game opponents, allies. +@ingroup ai + +![](computer.png) Computer controlled opponents are called "Bots". If a game supports them, they will be added with either `bot_minClients #` in the server console, or with the `addBot` command. + +## See also + +- @ref bot_profile +- @ref bot_cvars +- @ref bot_info +- @ref NSBot + +@{ +*/ + vector Route_SelectDestination( NSBot target ); - -var int autocvar_nav_linksize = 256; -var int autocvar_nav_radius = 8; - -void -_BotLog(string functionName, string msg) -{ - print(sprintf("%f ^xF05%s ^7: %s\n", time, functionName, msg)); -} - -/** Logs an bot system specific log message. - The console variable `bot_developer` has to be `1` for them to be visible. - -@param description(...) contains a formatted string containing a description. */ -#define BotLog(...) if (autocvar_bot_developer) _BotLog(__FUNC__, sprintf(__VA_ARGS__)) - -void -_BotEntLog(string className, string functionName, float edictNum, string warnMessage) -{ - print(sprintf("%f ^xF05%s (id: %d) ^7: %s\n", time, functionName, edictNum, warnMessage)); -} - -/** Logs an bot specific entity class log message. - The console variable `bot_developer` has to be `1` for them to be visible. - -@param description(...) contains a formatted string containing a description. */ -#define BotEntLog(...) if (autocvar_bot_developer) _BotEntLog(classname, __FUNC__, num_for_edict(this), sprintf(__VA_ARGS__)) - -var string autocvar_bot_prefix = ""; - -/** @} */ // end of bot \ No newline at end of file + +var int autocvar_nav_linksize = 256; +var int autocvar_nav_radius = 8; + +void +_BotLog(string functionName, string msg) +{ + print(sprintf("%f ^xF05%s ^7: %s\n", time, functionName, msg)); +} + +/** Logs an bot system specific log message. + The console variable `bot_developer` has to be `1` for them to be visible. + +@param description(...) contains a formatted string containing a description. */ +#define BotLog(...) if (autocvar_bot_developer) _BotLog(__FUNC__, sprintf(__VA_ARGS__)) + +void +_BotEntLog(string className, string functionName, float edictNum, string warnMessage) +{ + print(sprintf("%f ^xF05%s (id: %d) ^7: %s\n", time, functionName, edictNum, warnMessage)); +} + +/** Logs an bot specific entity class log message. + The console variable `bot_developer` has to be `1` for them to be visible. + +@param description(...) contains a formatted string containing a description. */ +#define BotEntLog(...) if (autocvar_bot_developer) _BotEntLog(classname, __FUNC__, num_for_edict(this), sprintf(__VA_ARGS__)) + +var string autocvar_bot_prefix = ""; + +/** @} */ // end of bot diff --git a/src/menu-vgui/background.qc b/src/client/api.h old mode 100755 new mode 100644 similarity index 68% rename from src/menu-vgui/background.qc rename to src/client/api.h index 7d29221a..8f431666 --- a/src/menu-vgui/background.qc +++ b/src/client/api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,21 +14,19 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define BACKGROUND_IMG "gfx/background" +#pragma target fte_5768 +#define CSQC + +#include "../shared/fteextensions.qc" +#include "../shared/api.h" +#include "../shared/input.h" +#include "api_func.h" void -Background_Init(void) +main(void) { - precache_pic(BACKGROUND_IMG); -} - -void -Background_Draw(vector vecSize) -{ - if (clientstate() == 2) { - if (!g_background) - drawfill([ 0, 0 ], vecSize, [ 0, 0, 0 ], 0.5f); - } else - drawpic([ 0, 0 ], BACKGROUND_IMG, vecSize, [ 1, 1, 1 ], 1.0f); + _client_main(); + _shared_main(); + HUD_Init(); } diff --git a/src/client/api.qc b/src/client/api.qc new file mode 100644 index 00000000..1068f668 --- /dev/null +++ b/src/client/api.qc @@ -0,0 +1,391 @@ +/* + * Copyright (c) 2024 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +/* + +This is the Client Game API. Used by client-side scriptobjects, hud progs etc. +There's no header because the main code is not supposed to use this. + +*/ + +/* view functions */ +float +Surface_ScreenWidth(void) +{ + return (g_vidsize[0]); +} + +float +Surface_ScreenHeight(void) +{ + return (g_vidsize[1]); +} + +vector +Surface_ScreenSize(void) +{ + return (g_vidsize); +} + +vector +Surface_HUDMins(void) +{ + return (g_hudmins); +} + +vector +Surface_HUDSize(void) +{ + return (g_hudres); +} + +/* player functions */ +float +Player_GetHealth(void) +{ + return (pSeat->m_ePlayer.health); +} + +float +Player_GetArmor(void) +{ + return (((NSClientPlayer)pSeat->m_ePlayer).armor); +} + +float +Player_GetStamina(void) +{ + return (((NSClientPlayer)pSeat->m_ePlayer).GetStamina()); +} + +int +Player_GetTeam(void) +{ + return (int)getplayerkeyfloat(pSeat->m_ePlayer.entnum-1, "*team"); +} + +bool +Player_HasItem(string itemName) +{ + return (((NSClientPlayer)pSeat->m_ePlayer).HasItem(itemName)); +} + +bool +Player_IsSprinting(string itemName) +{ + return ((NSClientPlayer)pSeat->m_ePlayer).IsSprinting(); +} + +bool +Player_IsCrouching(string itemName) +{ + return ((NSClientPlayer)pSeat->m_ePlayer).IsCrouching(); +} + +bool +Player_IsProne(string itemName) +{ + return ((NSClientPlayer)pSeat->m_ePlayer).IsProne(); +} + +bool +Player_IsStanding(string itemName) +{ + return ((NSClientPlayer)pSeat->m_ePlayer).IsStanding(); +} + +bool +Player_IsLeaning(string itemName) +{ + return ((NSClientPlayer)pSeat->m_ePlayer).IsLeaning(); +} + + +/* teamplay functions */ +string +Team_GetName(int teamNumber) +{ + return serverkey(sprintf("team_%i", teamNumber)); +} + +vector +Team_GetColor(int teamNumber) +{ + return g_vec_null; +} + +int +Team_GetScore(int teamNumber) +{ + return (int)serverkeyfloat(sprintf("teamscore_%i", teamNumber)); +} + +int +Team_GetPlayers(int teamNumber) +{ + return 0i; +} + +int +Team_GetCount(void) +{ + return (int)serverkeyfloat("teams"); +} + +bool +Weapon_IsValid(entity weaponEntity) +{ + NSWeapon weapon = (NSWeapon)weaponEntity; + + if (weapon) { + return (weapon.IsWeapon()); + } + + return (false); +} + +string +Weapon_GetTitle(entity weaponEntity) +{ + NSWeapon weapon = (NSWeapon)weaponEntity; + + if (weapon) { + return (weapon.m_strWeaponTitle); + } + + return "Unknown"; +} + +string +Weapon_GetIcon(entity weaponEntity) +{ + NSWeapon weapon = (NSWeapon)weaponEntity; + + if (weapon) { + return (weapon.m_icon); + } + + return "Unknown"; +} + +string +Weapon_GetSelectedIcon(entity weaponEntity) +{ + NSWeapon weapon = (NSWeapon)weaponEntity; + + if (weapon) { + return (weapon.m_iconSel); + } + + return "Unknown"; +} + +int +Weapon_GetSlot(entity weaponEntity) +{ + NSWeapon weapon = (NSWeapon)weaponEntity; + + if (weapon) { + return (weapon.m_iHudSlot); + } + + return -1i; +} + +int +Weapon_GetSlotPos(entity weaponEntity) +{ + NSWeapon weapon = (NSWeapon)weaponEntity; + + if (weapon) { + return (weapon.m_iHudSlotPos); + } + + return -1i; +} + +int +Weapon_GetClip(void) +{ + NSActor owner = (NSActor)pSeat->m_ePlayer; + NSWeapon weapon = owner.m_activeWeapon; + + if (weapon) { + return (weapon.m_iClip); + } + + return 0; +} + +int +Weapon_GetClipSize(void) +{ + NSActor owner = (NSActor)pSeat->m_ePlayer; + NSWeapon weapon = owner.m_activeWeapon; + + if (weapon) { + return (weapon.m_iClipSize); + } + + return 0; +} + +bool +Weapon_UsesSecondaryAmmo(void) +{ + NSActor owner = (NSActor)pSeat->m_ePlayer; + NSWeapon weapon = owner.m_activeWeapon; + + if (weapon) { + return weapon.UsesSecondaryAmmo(); + } + + return (false); +} + +int +Weapon_GetAmmo1(void) +{ + NSActor owner = (NSActor)pSeat->m_ePlayer; + NSWeapon weapon = owner.m_activeWeapon; + + if (weapon) { + return owner.GetReserveAmmo(weapon.m_primaryAmmoType); + } + + return -1i; +} + +int +Weapon_GetAmmo2(void) +{ + NSActor owner = (NSActor)pSeat->m_ePlayer; + NSWeapon weapon = owner.m_activeWeapon; + + if (weapon) { + return owner.GetReserveAmmo(weapon.m_secondaryAmmoType); + } + + return -1i; +} + +bool +Weapon_AmmoRequired(void) +{ + NSActor owner = (NSActor)pSeat->m_ePlayer; + NSWeapon weapon = owner.m_activeWeapon; + + if (weapon) { + return (weapon.m_fiAmmoRequired); + } + + return (false); +} + +entity +Weapon_GetActiveWeapon(void) +{ + return ((NSActor)pSeat->m_ePlayer).m_activeWeapon; +} + +entity +Weapon_GetFirstWeaponInInventory(void) +{ +#if 0 + return ((NSActor)pSeat->m_ePlayer).m_firstWeapon; +#else + return ((NSActor)pSeat->m_ePlayer).SortWeaponChain(); +#endif +} + +entity +Weapon_GetLastWeaponInInventory(void) +{ + return ((NSActor)pSeat->m_ePlayer).m_firstWeapon.m_prevWeapon; +} + +entity +Weapon_GetNextWeaponRelativeTo(entity weaponCheck) +{ + if (weaponCheck) + return ((NSWeapon)weaponCheck).m_nextWeapon; + + return __NULL__; +} + +entity +Weapon_GetPreviousWeaponRelativeTo(entity weaponCheck) +{ + if (weaponCheck) + return ((NSWeapon)weaponCheck).m_prevWeapon; + + return __NULL__; +} + +bool +Weapon_SelectWeapon(entity weaponCheck) +{ + if (weaponCheck) { + NSWeapon_SelectWeapon((NSWeapon)weaponCheck); + return (true); + } + + return (false); +} + +void +Draw_Rect(vector pos, vector size, vector rgb, float a) +{ + drawfill(pos, size, rgb, a); +} + +void +Draw_RectOutline(vector pos, vector size, float thickness, vector rgb, float a) +{ + drawrect(pos, size, thickness, rgb, a); +} + +void +Draw_RoundedBox(vector pos, vector size, vector rgb, float a) +{ + drawpic(pos, "textures/ui/m_topleft.tga", [16,16], rgb, a, 0); + drawpic(pos + [size[0] - 16, 0], "textures/ui/m_topright.tga", [16,16], rgb, a, 0); + drawpic(pos + [0, size[1] - 16], "textures/ui/m_bottomleft.tga", [16,16], rgb, a, 0); + drawpic(pos + [size[0] - 16, size[1] - 16], "textures/ui/m_bottomright.tga", [16,16], rgb, a, 0); + + if (size_x > 32) { + drawpic(pos + [16, 0], "textures/ui/m_top.tga", [size[0] - 32, 16], rgb, a, 0); + drawpic(pos + [16, size[1] - 16], "textures/ui/m_bottom.tga", [size[0] - 32, 16], rgb, a, 0); + } + + if (size_y > 32) { + drawpic(pos + [0, 16], "textures/ui/m_left.tga", [16, size[1] - 32], rgb, a, 0); + drawpic(pos + [size[0] - 16, 16], "textures/ui/m_right.tga", [16, size[1] - 32], rgb, a, 0); + drawpic(pos + [16, 16], "textures/ui/m_mid.tga", [size[0] - 32, size[1] - 32], rgb, a, 0); + } +} + +void +Draw_Line(float thickness, vector pos1, vector pos2, vector rgb, float a) +{ + drawline(thickness, pos1, pos2, rgb, a); +} + +void +Draw_Pic(vector pos, string material, vector size, vector rgb, float a) +{ + drawpic(pos, material, size, rgb, a); +} diff --git a/src/client/api_func.h b/src/client/api_func.h new file mode 100644 index 00000000..6f48b3b3 --- /dev/null +++ b/src/client/api_func.h @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2016-2024 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +/** Flags for 2D drawing operations. */ +typedef enum +{ + DRAWFLAG_NORMAL = 0, /**< The default. */ + DRAWFLAG_ADDITIVE, /**< Render with an additive blend mode. */ + DRAWFLAG_MODULATE, /**< Not implemented in FTEQW. */ + DRAWFLAG_2XMODULATE /**< Not implemented in FTEQW. */ +} drawflag_t; + +/** Defines the valid alignment flags for text fields. +@sa Font_DrawField */ +typedef enumflags +{ + AF_LEFT, + AF_TOP, + AF_RIGHT, + AF_BOTTOM +} alignflags_t; +#define AF_NONE 0 + +/** Representation of a font. */ +typedef struct +{ + int iID; /**< Internal ID, will be passed to 'drawfont' before rendering text. */ + int iScaleX; /**< Suggested maximum width of a character in the font. */ + int iScaleY; /**< Maximum height of a chracter in the font. */ + vector vecColor; /**< Suggested default color of the font. */ + float flAlpha; /**< Suggested default alpha of the font. */ + int iFlags; /**< Rendering flags that the font posesses. @sa drawflag_t */ + string hexColor; +} font_s; + +/** @defgroup hudc HudC + @brief Client-side Game-Logic API + @ingroup multiprogs + +APIs used by HudC progs and the client progs exclusively. + +@{ +*/ + +/* Font library */ +typedef struct +{ + float GetID(font_s); + void Load(string,font_s &); + string RGBtoHex(vector); + int GetHeight(font_s); + float StringWidth(string,bool,font_s); +} fontAPI_t; +var fontAPI_t font; + + +/* Surface library */ +typedef struct +{ + float Width(void); + float Height(void); + vector HUDMins(void); + vector HUDSize(void); +} surfaceAPI_t; +var surfaceAPI_t screen; + +/* Surface library */ +typedef struct +{ + void Rect(vector, vector, vector, float); + void RectOutline(vector, vector, float, vector, float); + void RoundedBox(vector, vector, vector, float); + void Line(float, vector, vector, vector, float); + void Pic(vector, string, vector, vector, float); + void Text(vector,string,font_s); + void Text_A(vector,string,float,font_s); + void Text_RGB(vector,string,vector,font_s); + void Text_RGBA(vector,string,vector,float,font_s); + void RText(vector,string,font_s); + void RText_A(vector,string,float,font_s); + void RText_RGB(vector,string,vector,font_s); + void RText_RGBA(vector,string,vector,float,font_s); + void TextField(vector,vector,string,font_s,alignflags_t); + void TextFieldAtHeight(vector,vector,int,string,font_s,alignflags_t); +} drawAPI_t; +var drawAPI_t draw; + +/* Player library */ +typedef struct +{ + float GetArmor(void); + float GetHealth(void); + float GetStamina(void); + int GetTeam(void); + bool IsStanding(void); + bool IsLeaning(void); + bool IsSprinting(void); + bool IsCrouched(void); + bool IsProne(void); + bool HasItem(string); +} playerAPI_t; +var playerAPI_t player; + +/* Weapon library */ +typedef struct +{ + bool IsValid(entity); + string GetTitle(entity); + int GetSlot(entity); + int GetSlotPos(entity); + string GetIcon(entity); + string GetSelectedIcon(entity); + int GetAmmo1(void); + int GetAmmo2(void); + int GetClip(void); + int GetClipSize(void); + bool UsesSecondaryAmmo(void); + bool AmmoRequired(void); + + entity GetActiveWeapon(void); + entity GetFirstWeaponInInventory(void); + entity GetLastWeaponInInventory(void); + + entity GetNextWeaponRelativeTo(entity); + entity GetPreviousWeaponRelativeTo(entity); + + void SelectWeapon(entity); +} weaponAPI_t; +var weaponAPI_t weapon; + + +/** @} */ // end of hudC + +/* To be implemented by HUD */ +void HUD_Init(void); + +__variant +linkToClientProgs(string funcName) +{ + static void empty(void) + { + print("Called unimplemented client-side API call.\n"); + breakpoint(); + } + + void *func = externvalue(0, funcName); + + if (func) { + return ((__variant)func); + } else { + return (empty); + } +} + +void +_client_main(void) +{ + font.GetHeight = linkToClientProgs("Font_GetHeight"); + font.GetID = linkToClientProgs("Font_GetID"); + font.Load = linkToClientProgs("Font_Load"); + font.RGBtoHex = linkToClientProgs("Font_RGBtoHex"); + font.StringWidth = linkToClientProgs("Font_StringWidth"); + + screen.Width = linkToClientProgs("Surface_ScreenHeight"); + screen.Height = linkToClientProgs("Surface_ScreenHeight"); + + screen.HUDMins = linkToClientProgs("Surface_HUDMins"); + screen.HUDSize = linkToClientProgs("Surface_HUDSize"); + + player.GetHealth = linkToClientProgs("Player_GetHealth"); + player.GetArmor = linkToClientProgs("Player_GetArmor"); + player.GetStamina = linkToClientProgs("Player_GetStamina"); + player.GetTeam = linkToClientProgs("Player_GetTeam"); + player.HasItem = linkToClientProgs("Player_HasItem"); + player.IsStanding = linkToClientProgs("Player_IsStanding"); + player.IsLeaning = linkToClientProgs("Player_IsLeaning"); + player.IsSprinting = linkToClientProgs("Player_IsSprinting"); + player.IsCrouched = linkToClientProgs("Player_IsCrouched"); + player.IsProne = linkToClientProgs("Player_IsProne"); + + weapon.IsValid = linkToClientProgs("Weapon_IsValid"); + weapon.GetTitle = linkToClientProgs("Weapon_GetTitle"); + weapon.GetIcon = linkToClientProgs("Weapon_GetIcon"); + weapon.GetSelectedIcon = linkToClientProgs("Weapon_GetSelectedIcon"); + weapon.GetSlot = linkToClientProgs("Weapon_GetSlot"); + weapon.GetSlotPos = linkToClientProgs("Weapon_GetSlotPos"); + weapon.GetAmmo1 = linkToClientProgs("Weapon_GetAmmo1"); + weapon.GetAmmo2 = linkToClientProgs("Weapon_GetAmmo2"); + weapon.GetClip = linkToClientProgs("Weapon_GetClip"); + weapon.GetClipSize = linkToClientProgs("Weapon_GetClipSize"); + weapon.UsesSecondaryAmmo = linkToClientProgs("Weapon_UsesSecondaryAmmo"); + weapon.AmmoRequired = linkToClientProgs("Weapon_AmmoRequired"); + weapon.GetActiveWeapon = linkToClientProgs("Weapon_GetActiveWeapon"); + weapon.GetFirstWeaponInInventory = linkToClientProgs("Weapon_GetFirstWeaponInInventory"); + weapon.GetLastWeaponInInventory = linkToClientProgs("Weapon_GetLastWeaponInInventory"); + weapon.GetNextWeaponRelativeTo = linkToClientProgs("Weapon_GetNextWeaponRelativeTo"); + weapon.GetPreviousWeaponRelativeTo = linkToClientProgs("Weapon_GetPreviousWeaponRelativeTo"); + weapon.SelectWeapon = linkToClientProgs("Weapon_SelectWeapon"); + + draw.Rect = linkToClientProgs("Draw_Rect"); + draw.RectOutline = linkToClientProgs("Draw_RectOutline"); + draw.RoundedBox = linkToClientProgs("Draw_RoundedBox"); + draw.Line = linkToClientProgs("Draw_Line"); + draw.Pic = linkToClientProgs("Draw_Pic"); + draw.TextField = linkToClientProgs("Font_DrawField"); + draw.TextFieldAtHeight = linkToClientProgs("Font_DrawFieldAtHeight"); + draw.RText = linkToClientProgs("Font_DrawRText"); + draw.RText_A = linkToClientProgs("Font_DrawRText_A"); + draw.RText_RGB = linkToClientProgs("Font_DrawRText_RGB"); + draw.RText_RGBA = linkToClientProgs("Font_DrawRText_RGBA"); + draw.Text = linkToClientProgs("Font_DrawText"); + draw.Text_A= linkToClientProgs("Font_DrawText_A"); + draw.Text_RGB= linkToClientProgs("Font_DrawText_RGB"); + draw.Text_RGBA = linkToClientProgs("Font_DrawText_RGBA"); +} diff --git a/src/client/cmd.qc b/src/client/cmd.qc index e1e810be..f6dbfef3 100644 --- a/src/client/cmd.qc +++ b/src/client/cmd.qc @@ -14,6 +14,9 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +void Commandmenu_Open(void); +void Commandmenu_Close(void); + static void CMD_testPointLight(void) { @@ -490,6 +493,7 @@ Cmd_Parse(string sCMD) case "removeInventoryItem": case "removeAllInventoryItems": case "listAmmo": + case "joinTeam": localcmd(sprintf("cmd %s\n", sCMD)); break; @@ -504,8 +508,18 @@ Cmd_Parse(string sCMD) break; case "bobdn": break; + + case "+commandmenu": + Commandmenu_Open(); + break; + case "-commandmenu": + Commandmenu_Close(); + break; + case "ragdollCreate": + NSRagdoll_Create(argv(1)); + break; default: - return (false); + return HUD_ConsoleCommand(sCMD); } return (true); } @@ -535,6 +549,7 @@ Cmd_Init(void) registercommand("listServerEntityDef"); registercommand("listInventory"); registercommand("listAmmo"); + registercommand("ragdollCreate"); /* server commands */ registercommand("addBot"); @@ -613,6 +628,9 @@ Cmd_Init(void) registercommand("vote"); registercommand("callvote"); + /* teamplay */ + registercommand("joinTeam"); + /* motd */ registercommand("motd"); @@ -628,6 +646,10 @@ Cmd_Init(void) registercommand("slot9"); registercommand("slot10"); + /* commandmenu */ + registercommand("+commandmenu"); + registercommand("-commandmenu"); + /* scoreboard */ registercommand("+showscores"); registercommand("-showscores"); diff --git a/src/client/commandmenu.qc b/src/client/commandmenu.qc new file mode 100644 index 00000000..5553eeed --- /dev/null +++ b/src/client/commandmenu.qc @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2024 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +VGUIWidget g_uiCommandMenu; + +void +Commandmenu_Init(void) +{ + filestream commandFile; + string line; + VGUICommandButton lastButton = __NULL__; + VGUICommandButton newButton = __NULL__; + int braceDepth = 0i; + vector buttonPos = g_vec_null; + vector mainPos = g_vec_null; + string mapFilter = ""; + string ourMap = strtolower(serverkey("map")); + + commandFile = fopen("commandmenu.txt", FILE_READ); + + if (commandFile < 0) { + NSWarning("No command-menu. Missing commandmenu.txt"); + return; + } + + g_uiCommandMenu = spawn(VGUIWidget); + + while ((line = fgets(commandFile))) { + int tokensPerLine = tokenize_console(line); + + if (argv(0) == "{") { + if (!newButton) { + NSError("Cannot add sub-menu to non-existant button."); + fclose(commandFile); + return; + } + + lastButton = newButton; + braceDepth++; + + /* positions are relative to the parent, not absolute */ + buttonPos = [lastButton.GetSizeWidth(), 0]; + } else if (argv(0) == "}") { /* end of button menu */ + braceDepth--; + mapFilter = ""; + + if (braceDepth == 0) { + buttonPos = mainPos; + } else { + buttonPos = lastButton.GetPos() + [0, lastButton.GetSizeHeight()]; + lastButton = (VGUICommandButton)lastButton.m_parent; + } + } else if (tokensPerLine >= 2) { + string buttonTitle = ""; + string buttonCommand = ""; + string buttonKey = ""; + + if (tokensPerLine == 2) { + buttonKey = (argv(0)); + buttonTitle = (argv(1)); + } else if (argv(0) == "MAP") { + mapFilter = strtolower(argv(1)); + buttonKey = (argv(2)); + buttonTitle = (argv(3)); + } else if (substring(argv(0), 0, 4) == "TEAM") { + //newButton.SetTeamCondition(argv(0)); + buttonKey = (argv(1)); + buttonTitle = (argv(2)); + buttonCommand = (argv(3)); + } else if (argv(0) == "CUSTOM") { + buttonKey = (argv(1)); + buttonTitle = (argv(2)); + buttonCommand = (argv(3)); + } else if (tokensPerLine == 3) { + buttonKey = (argv(0)); + buttonTitle = (argv(1)); + buttonCommand = (argv(2)); + } + + /* if this group is filtered, don't add it. */ + if (STRING_SET(mapFilter)) { + if (mapFilter != ourMap) { + continue; + } + } + + newButton = spawn(VGUICommandButton); + newButton.SetPos(buttonPos); + newButton.SetSize([192,24]); + newButton.SetKeyEquivalent(buttonKey); + newButton.SetTitle(buttonTitle); + + if (substring(buttonCommand, 0, 1) == "!") { + newButton.SetExec(strtolower(substring(buttonCommand, 1,-1))); + } else { + newButton.SetExec(buttonCommand); + } + + if (braceDepth == 0) { + g_uiCommandMenu.Add(newButton); + buttonPos = mainPos = newButton.GetPos() + [0, newButton.GetSizeHeight()]; + } else { + buttonPos[1] += newButton.GetSizeHeight(); + lastButton.Add(newButton); + } + } + } + + fclose(commandFile); +} + +void +Commandmenu_Draw(void) +{ + if (pSeat->m_bCommandMenu == false) + return; + + if (g_uiCommandMenu) + g_uiCommandMenu.Draw(); +} + +bool +Commandmenu_Input(float flEvType, float flScanX, float flCharY, float flDevID) +{ + if (pSeat->m_bCommandMenu == false) + return (false); + + if (!g_uiCommandMenu) + return (false); + + return g_uiCommandMenu.Input(flEvType, flScanX, flCharY, flDevID); +} + +void +Commandmenu_Open(void) +{ + pSeat->m_bCommandMenu = true; +} + +void +Commandmenu_Close(void) +{ + pSeat->m_bCommandMenu = false; +} diff --git a/src/client/crosshair.h b/src/client/crosshair.h index 643ecf5d..7b84bca1 100644 --- a/src/client/crosshair.h +++ b/src/client/crosshair.h @@ -26,6 +26,12 @@ @{ */ + +/** Returns the end-coordinates for a crosshair of a given size. + +@param sizeXY is the size in pixels it is meant to take up on screen. */ +vector Cross_GetPos(vector sizeXY); + /** Draws a crosshair on the screen with the desired material and size. @param materialPath is the material to use. @@ -76,4 +82,4 @@ void Cross_DrawSubRGB(string materialPath, vector sizeXY, vector sourcePosXY, ve @param alphaValue is the alpha values to use on the whole surface.*/ void Cross_DrawSubRGBA(string materialPath, vector sizeXY, vector sourcePosXY, vector sourceSizeXY, vector colorRGB, float alphaValue); -/** @} */ // end of client \ No newline at end of file +/** @} */ // end of client diff --git a/src/client/crosshair.qc b/src/client/crosshair.qc index c22c19d8..44ad6d08 100644 --- a/src/client/crosshair.qc +++ b/src/client/crosshair.qc @@ -14,6 +14,38 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +vector +Cross_GetPos(vector sizeXY) +{ + vector crossPos; + + if (cvar("pm_thirdPerson") < 1) { + crossPos = g_hudmins + (g_hudres / 2) + [-(sizeXY[0]/2),-(sizeXY[1]/2)]; + crossPos[0] = rint(crossPos[0]); + crossPos[1] = rint(crossPos[1]); + + /* terrible hack to deal with engine's bad autoscale positioning */ + if (cvar("vid_conautoscale") > 1) { + crossPos[0] -= 0.25f; + crossPos[1] -= 0.25f; + } + } else { + vector vecSrc; + vector vecDst; + NSClientPlayer pl = (NSClientPlayer)pSeat->m_ePlayer; + + vecSrc = pSeat->m_vecPredictedOrigin + pSeat->m_ePlayer.view_ofs; + makevectors(view_angles); + vecDst = (vecSrc + v_forward * 4096); + traceline(vecSrc, vecDst, MOVE_NORMAL, pSeat->m_ePlayer); + crossPos = project(trace_endpos) + [-(sizeXY[0]/2),-(sizeXY[1]/2)]; + crossPos[0] = rint(crossPos[0]); + crossPos[1] = rint(crossPos[1]); + } + + return (crossPos); +} + void Cross_Draw(string materialPath, vector sizeXY) { @@ -47,32 +79,11 @@ Cross_DrawSubRGB(string materialPath, vector sizeXY, vector sourcePosXY, vector void Cross_DrawSubRGBA(string materialPath, vector sizeXY, vector sourcePosXY, vector sourceSizeXY, vector colorRGB, float alphaValue) { - static vector crossPos; + vector crossPos = Cross_GetPos(sizeXY); if (cvar("pm_thirdPerson") < 1) { - crossPos = g_hudmins + (g_hudres / 2) + [-(sizeXY[0]/2),-(sizeXY[1]/2)]; - crossPos[0] = rint(crossPos[0]); - crossPos[1] = rint(crossPos[1]); - - /* terrible hack to deal with engine's bad autoscale positioning */ - if (cvar("vid_conautoscale") > 1) { - crossPos[0] -= 0.25f; - crossPos[1] -= 0.25f; - } - drawsubpic(crossPos, sizeXY, materialPath, sourcePosXY, sourceSizeXY, colorRGB, alphaValue, DRAWFLAG_NORMAL); } else { - vector vecSrc; - vector vecDst; - NSClientPlayer pl = (NSClientPlayer)pSeat->m_ePlayer; - - vecSrc = pSeat->m_vecPredictedOrigin + pSeat->m_ePlayer.view_ofs; - makevectors(view_angles); - vecDst = (vecSrc + v_forward * 4096); - traceline(vecSrc, vecDst, MOVE_NORMAL, pSeat->m_ePlayer); - crossPos = project(trace_endpos) + [-(sizeXY[0]/2),-(sizeXY[1]/2)]; - crossPos[0] = rint(crossPos[0]); - crossPos[1] = rint(crossPos[1]); drawsubpic(crossPos, sizeXY, materialPath, sourcePosXY, sourceSizeXY, colorRGB, alphaValue, DRAWFLAG_NORMAL); } -} \ No newline at end of file +} diff --git a/src/client/defs.h b/src/client/defs.h index 856ad6e6..926981d6 100644 --- a/src/client/defs.h +++ b/src/client/defs.h @@ -14,6 +14,8 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "api_func.h" +#include "../shared/api.h" #include "../shared/entityDef.h" #include "text.h" #include "textmenu.h" @@ -24,6 +26,7 @@ #include "NSView.h" #include "NSRadar.h" #include "crosshair.h" +#include "hud.h" var bool g_net_debug = false; var bool g_cheats = false; @@ -140,6 +143,7 @@ int Util_GetMaxPlayers(void); font_s FONT_16; font_s FONT_20; font_s FONT_CON; +font_s FONT_CENTERPRINT; //var string g_shellchrome; var float g_shellchromeshader; @@ -209,7 +213,6 @@ void drawrect(vector pos, vector sz, float thickness, vector rgb, float al, opti drawfill(pos + [sz[0] - thickness, thickness], [thickness, sz[1] - (thickness * 2)], rgb, al, dfl); } - /** Like drawpic, but instead of screen coords, it will take world coords. Will project the 2D image relative to the active NSView that we're currently rendering in (g_view). So it may only be called within certain contexts. */ @@ -410,6 +413,7 @@ struct int m_iSprinting; int m_iSelectedWeapon; + bool m_bCommandMenu; } g_seats[4], *pSeat; .float modelindex2; diff --git a/src/client/entities.qc b/src/client/entities.qc index c6826553..88a65792 100644 --- a/src/client/entities.qc +++ b/src/client/entities.qc @@ -22,12 +22,18 @@ Entity_EntityUpdate(float type, float new) case ENT_ENTITY: NSENTITY_READENTITY(NSEntity, new) break; + case ENT_SOUND: + NSENTITY_READENTITY(NSSound, new) + break; case ENT_PMOVEVARS: NSENTITY_READENTITY(NSPMoveVars, new) break; case ENT_ENTITYRENDERABLE: NSENTITY_READENTITY(NSRenderableEntity, new) break; + case ENT_RAGDOLL: + NSENTITY_READENTITY(NSRagdoll, new) + break; case ENT_SURFPROP: NSENTITY_READENTITY(NSSurfacePropEntity, new) break; diff --git a/src/client/entry.qc b/src/client/entry.qc index 103dd842..f518300c 100644 --- a/src/client/entry.qc +++ b/src/client/entry.qc @@ -72,6 +72,7 @@ CSQC_Init(float apilevel, string enginename, float engineversion) Way_Init(); Materials_Init(); MOTD_Init(); + Commandmenu_Init(); /* let the menu know we're a multi or a singleplayer game */ if (serverkeyfloat("sv_playerslots") == 1) @@ -87,11 +88,8 @@ CSQC_Init(float apilevel, string enginename, float engineversion) g_overview = NSRadar::InitForCurrentMap(); - Sound_Precache("Player.DenyWeaponSelection"); - Sound_Precache("Player.WeaponSelected"); - Sound_Precache("Player.WeaponSelectionMoveSlot"); - Sound_Precache("Player.WeaponSelectionOpen"); - Sound_Precache("Player.WeaponSelectionClose"); + + HUD_Init(); /* end msg */ NSLog("Client game initialized."); @@ -121,6 +119,7 @@ CSQC_RendererRestarted(string rstr) Font_Load("fonts/font16.font", FONT_16); Font_Load("fonts/font20.font", FONT_20); Font_Load("fonts/fontcon.font", FONT_CON); + Font_Load("fonts/centerprint.font", FONT_CENTERPRINT); /* Particles */ PART_DUSTMOTE = particleeffectnum("volume.dustmote"); @@ -135,7 +134,7 @@ CSQC_RendererRestarted(string rstr) Scores_Init(); View_Init(); ClientGame_RendererRestart(rstr); - HUD_Init(); + HUD_RendererRestarted(); /* GS-Entbase */ Fade_Reload(); @@ -228,6 +227,7 @@ CSQC_UpdateView(float w, float h, float focus) g_vidsize[0] = w; g_vidsize[1] = h; ClientGame_InitDone(); + Sky_Update(true); } } @@ -241,7 +241,7 @@ CSQC_UpdateView(float w, float h, float focus) /* these have to be checked every frame */ Fog_Update(); - Sky_Update(FALSE); + Sky_Update(false); cvar_set("_background", serverkey("background")); /* ensure background maps do not get paused */ @@ -311,6 +311,7 @@ CSQC_UpdateView(float w, float h, float focus) /* 2D calls happen here, after rendering is done */ CSQC_Update2D(w, h, focus); + Commandmenu_Draw(); EFX_UpdateListener(g_view); DSP_UpdateSoundscape(g_view); @@ -385,7 +386,12 @@ CSQC_InputEvent(float fEventType, float fKey, float fCharacter, float fDeviceID) g_vecMousePos = getmousepos(); - bool vgui_pressed = VGUI_Input(fEventType, fKey, fCharacter, fDeviceID); + bool vgui_pressed; + vgui_pressed = Commandmenu_Input(fEventType, fKey, fCharacter, fDeviceID); + + if (!vgui_pressed) { + vgui_pressed = VGUI_Input(fEventType, fKey, fCharacter, fDeviceID); + } if (g_vguiWidgetCount) { setcursormode(TRUE, "gfx/cursor", [0,0,0], 1.0f); @@ -414,7 +420,20 @@ CSQC_Input_Frame(void) if (me.classname == "player" || me.classname == "spectator") { NSClient pl = (NSClient)me; pl.SharedInputFrame(); + float delayInputs = HUD_ClientInputFrame(input_buttons); + + if (delayInputs > 0.0f) { + pSeat->m_flInputBlockTime = time + delayInputs; + } + pl.ClientInputFrame(); + + if (pSeat->m_flInputBlockTime > time) { + input_buttons &= ~INPUT_PRIMARY; + input_buttons &= ~INPUT_SECONDARY; + pSeat->m_iInputAttack2 = false; + return; + } } } diff --git a/src/client/font.h b/src/client/font.h index 32dab818..6cc5e65e 100644 --- a/src/client/font.h +++ b/src/client/font.h @@ -40,6 +40,7 @@ typedef enumflags AF_RIGHT, AF_BOTTOM } alignflags_t; +#define AF_NONE 0 /** Representation of a font. */ typedef struct @@ -50,6 +51,7 @@ typedef struct vector vecColor; /**< Suggested default color of the font. */ float flAlpha; /**< Suggested default alpha of the font. */ int iFlags; /**< Rendering flags that the font posesses. @sa drawflag_t */ + string hexColor; } font_s; /** Load a desired .font definition into memory. @@ -162,4 +164,4 @@ porting old code. @return the internal 'drawfont' id of the specified font. */ float Font_GetID(font_s fnt); -/** @} */ // end of client \ No newline at end of file +/** @} */ // end of client diff --git a/src/client/font.qc b/src/client/font.qc index 1c3448f7..0ecdffdf 100644 --- a/src/client/font.qc +++ b/src/client/font.qc @@ -31,6 +31,7 @@ Font_Load(string strFile, font_s &fntNew) fntNew.iID = 0; fntNew.iScaleX = fntNew.iScaleY = 12; fntNew.vecColor = [1,1,1]; + fntNew.hexColor = "^xFFF"; fntNew.flAlpha = 1.0f; fntNew.iFlags = 0; @@ -44,6 +45,7 @@ Font_Load(string strFile, font_s &fntNew) switch (argv(0)) { case "color": fntNew.vecColor = stov(argv(1)) / 255; + fntNew.hexColor = Font_RGBtoHex(fntNew.vecColor); break; case "alpha": fntNew.flAlpha = stof(argv(1)) / 255; @@ -175,7 +177,7 @@ Font_DrawField(vector vecOrigin, vector vecSize, string strText, font_s fnt, ali drawfont = (float)fnt.iID; drawfontscale[0] = (float)fnt.iScaleX / 8; drawfontscale[1] = (float)fnt.iScaleY / 8; - drawtextfield(vecOrigin, vecSize, (float)iAlignFlags, strText); + drawtextfield(vecOrigin, vecSize, (float)iAlignFlags, strcat(fnt.hexColor, strText)); drawfont = 0; drawfontscale = [1,1,0]; } diff --git a/src/client/hud.h b/src/client/hud.h new file mode 100644 index 00000000..ba0def16 --- /dev/null +++ b/src/client/hud.h @@ -0,0 +1,13 @@ +void HUD_Init(void); +void HUD_Draw(void); +void HUD_DrawSpectator(void); +void HUD_SendStat(string, string); +float HUD_ClientInputFrame(float); +bool HUD_ConsoleCommand(string); + +void HUDProgs_Init(void); +void HUDProgs_Draw(void); +void HUDProgs_DrawSpectator(void); +void HUDProgs_SendStat(string, string); +float HUDProgs_ClientInputFrame(float); +bool HUDProgs_ConsoleCommand(string); diff --git a/src/client/hud.qc b/src/client/hud.qc new file mode 100644 index 00000000..a394298e --- /dev/null +++ b/src/client/hud.qc @@ -0,0 +1,156 @@ + +var float g_flHUDProgs; +var void(void) g_hudInit; +var void(void) g_hudDraw; +var void(void) g_hudDrawSpectator; +var void(string, string) g_hudSendStat; +var void(string) g_hudSwitchedWeapon; +var float(float) g_hudInputFrame; +var bool(string) g_hudConsoleCommand; +var void(void) g_hudRendererRestarted; + +void +HUDProgs_Init(void) +{ + g_flHUDProgs = addprogs("hud.dat"); + + if (g_flHUDProgs > 0) { + g_hudInit = externvalue(g_flHUDProgs, "main"); + g_hudDraw = externvalue(g_flHUDProgs, "HUD_Draw"); + g_hudDrawSpectator = externvalue(g_flHUDProgs, "HUD_DrawSpectator"); + g_hudSendStat = externvalue(g_flHUDProgs, "HUD_SendStat"); + g_hudSwitchedWeapon = externvalue(g_flHUDProgs, "HUD_WeaponSwitched"); + g_hudInputFrame = externvalue(g_flHUDProgs, "HUD_InputFrame"); + g_hudConsoleCommand = externvalue(g_flHUDProgs, "HUD_ConsoleCommand"); + g_hudRendererRestarted = externvalue(g_flHUDProgs, "HUD_RendererRestarted"); + + if (g_hudInit) { + g_hudInit(); + } else { + NSError("HUD progs does not have a main function."); + } + } +} + +void +HUDProgs_RendererRestarted(void) +{ + if (g_flHUDProgs > 0) { + if (g_hudRendererRestarted) { + g_hudRendererRestarted(); + } + } +} + +void +HUDProgs_Draw(void) +{ + if (g_flHUDProgs > 0) { + if (g_hudDraw) { + externset(g_flHUDProgs, clframetime, "clframetime"); + g_hudDraw(); + } + } +} + + void +HUDProgs_DrawSpectator(void) +{ + if (g_flHUDProgs > 0) { + if (g_hudDrawSpectator) { + g_hudDrawSpectator(); + } + } +} + +void +HUDProgs_SendStat(string statName, string statValue) +{ + if (g_flHUDProgs > 0) { + if (g_hudSendStat) { + g_hudSendStat(statName, statValue); + } + } +} + +void +HUDProgs_SwitchedToWeapon(string weaponName) +{ + if (g_flHUDProgs > 0) { + if (g_hudSwitchedWeapon) { + g_hudSwitchedWeapon(weaponName); + } + } +} + +float +HUDProgs_ClientInputFrame(float inputFrame) +{ + if (g_flHUDProgs > 0) { + if (g_hudInputFrame) { + return g_hudInputFrame(inputFrame); + } + } + + return (0.0f); +} + +bool +HUDProgs_ConsoleCommand(string commandString) +{ + if (g_flHUDProgs > 0) { + if (g_hudConsoleCommand) { + return g_hudConsoleCommand(commandString); + } + } + + return (false); +} + +__weak void +HUD_Init(void) +{ + HUDProgs_Init(); +} + +__weak void +HUD_RendererRestarted(void) +{ + HUDProgs_RendererRestarted(); +} + +__weak void +HUD_Draw(void) +{ + HUDProgs_Draw(); +} + +__weak void +HUD_DrawSpectator(void) +{ + HUDProgs_DrawSpectator(); +} + +__weak void +HUD_SendStat(string statName, string statValue) +{ + HUDProgs_SendStat(statName, statValue); +} + +__weak void +HUD_SwitchedToWeapon(string weaponName) +{ + HUDProgs_SwitchedToWeapon(weaponName); +} + +__weak float +HUD_ClientInputFrame(float inputButtons) +{ + return HUDProgs_ClientInputFrame(inputButtons); +} + +__weak bool +HUD_ConsoleCommand(string commandString) +{ + return HUDProgs_ConsoleCommand(commandString); +} diff --git a/src/client/include.src b/src/client/include.src index 2fdfc269..a413d0d6 100644 --- a/src/client/include.src +++ b/src/client/include.src @@ -2,6 +2,7 @@ NSInteractiveSurface.qc NSView.qc NSRadar.qc +hud.qc fog.qc font.qc sky.qc @@ -24,7 +25,9 @@ detailtex.qc shake.qc cmd.qc event.qc +commandmenu.qc entry.qc crosshair.qc util.qc +api.qc #endlist diff --git a/src/client/prints.qc b/src/client/prints.qc index 5f8a848d..3fc25572 100644 --- a/src/client/prints.qc +++ b/src/client/prints.qc @@ -57,8 +57,8 @@ Print_DrawCenterprint(void) vecPos[1] = g_hudmins[1] + (g_hudres[1] / 2) - (pSeat->m_iCenterprintLines - 4) - 69; for (int i = 0; i < (pSeat->m_iCenterprintLines); i++) { - vecPos[0] = g_hudmins[0] + (g_hudres[0] / 2) - (stringwidth(pSeat->m_strCenterprintBuffer[i], TRUE, '12 12') / 2); - Font_DrawText_A(vecPos, pSeat->m_strCenterprintBuffer[i], pSeat->m_flCenterprintAlpha, FONT_CON); + vecPos[0] = g_hudmins[0] + (g_hudres[0] / 2) - (stringwidth(pSeat->m_strCenterprintBuffer[i], TRUE, '18 18') / 2); + Font_DrawText_A(vecPos, pSeat->m_strCenterprintBuffer[i], pSeat->m_flCenterprintAlpha, FONT_CENTERPRINT); vecPos[1] += 8; } } diff --git a/src/client/sky.qc b/src/client/sky.qc index 8d8534fc..0c21f890 100644 --- a/src/client/sky.qc +++ b/src/client/sky.qc @@ -30,7 +30,7 @@ Sky_Update(int force) //print(sprintf("SKY PREFIX: %S\n", skyPrefix)); /* is it a Source Engine material? */ - if (skyPrefix == "sky_") { + if (fileExists(strcat("materials/skybox/", g_strSkyName, "bk.vmt")) == true) { skyPath = strcat("materials/skybox/", g_strSkyName); } else { skyPath = g_strSkyName; diff --git a/src/client/spawnmenu.qc b/src/client/spawnmenu.qc new file mode 100644 index 00000000..177d5cc4 --- /dev/null +++ b/src/client/spawnmenu.qc @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2024 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +VGUIWidget g_uiSpawnMenu; + +void +SpawnMenu_Init(void) +{ + filestream commandFile; + string line; + VGUICommandButton lastButton; + VGUICommandButton newButton; + int braceDepth = 0i; + vector buttonPos = g_vec_null; + vector mainPos = g_vec_null; + string mapFilter = ""; + string ourMap = strtolower(serverkey("map")); + + commandFile = fopen("commandmenu.txt", FILE_READ); + + if (commandFile < 0) { + NSLog("Ignoring missing commandmenu.txt"); + return; + } + + g_uiSpawnMenu = spawn(VGUIWidget); + + while ((line = fgets(commandFile))) { + int tokensPerLine = tokenize_console(line); + + if (argv(0) == "{") { + if (!newButton) { + NSError("Cannot add sub-menu to non-existant button."); + fclose(commandFile); + return; + } + + lastButton = newButton; + braceDepth++; + + /* positions are relative to the parent, not absolute */ + buttonPos = [lastButton.GetSizeWidth(), 0]; + } else if (argv(0) == "}") { /* end of button menu */ + braceDepth--; + mapFilter = ""; + + if (braceDepth == 0) { + buttonPos = mainPos; + } else { + buttonPos = lastButton.GetPos() + [0, lastButton.GetSizeHeight()]; + lastButton = (VGUICommandButton)lastButton.m_parent; + } + } else if (tokensPerLine >= 2) { + string buttonTitle = ""; + string buttonCommand = ""; + string buttonKey = ""; + + if (tokensPerLine == 2) { + buttonKey = (argv(0)); + buttonTitle = (argv(1)); + } else if (argv(0) == "MAP") { + mapFilter = strtolower(argv(1)); + buttonKey = (argv(2)); + buttonTitle = (argv(3)); + } else if (substring(argv(0), 0, 4) == "TEAM") { + //newButton.SetTeamCondition(argv(0)); + buttonKey = (argv(1)); + buttonTitle = (argv(2)); + buttonCommand = (argv(3)); + } else if (argv(0) == "CUSTOM") { + buttonKey = (argv(1)); + buttonTitle = (argv(2)); + buttonCommand = (argv(3)); + } else if (tokensPerLine == 3) { + buttonKey = (argv(0)); + buttonTitle = (argv(1)); + buttonCommand = (argv(2)); + } + + /* if this group is filtered, don't add it. */ + if (STRING_SET(mapFilter)) { + if (mapFilter != ourMap) { + continue; + } + } + + newButton = spawn(VGUICommandButton); + newButton.SetPos(buttonPos); + newButton.SetSize([192,24]); + newButton.SetKeyEquivalent(buttonKey); + newButton.SetTitle(buttonTitle); + + if (substring(buttonCommand, 0, 1) == "!") { + newButton.SetExec(strtolower(substring(buttonCommand, 1,-1))); + } else { + newButton.SetExec(buttonCommand); + } + + if (braceDepth == 0) { + g_uiSpawnMenu.Add(newButton); + buttonPos = mainPos = newButton.GetPos() + [0, newButton.GetSizeHeight()]; + } else { + buttonPos[1] += newButton.GetSizeHeight(); + lastButton.Add(newButton); + } + } + } + + fclose(commandFile); +} + +void +SpawnMenu_Draw(void) +{ + if (pSeat->m_bSpawnMenu == false) + return; + + if (g_uiSpawnMenu) + g_uiSpawnMenu.Draw(); +} + +bool +SpawnMenu_Input(float flEvType, float flScanX, float flCharY, float flDevID) +{ + if (pSeat->m_bSpawnMenu == false) + return; + + if (!g_uiSpawnMenu) + return (false); + + return g_uiSpawnMenu.Input(flEvType, flScanX, flCharY, flDevID); +} + +void +SpawnMenu_Open(void) +{ + pSeat->m_bSpawnMenu = true; +} + +void +SpawnMenu_Close(void) +{ + pSeat->m_bSpawnMenu = false; +} diff --git a/src/client/view.qc b/src/client/view.qc index 1ffabab8..58ad960d 100644 --- a/src/client/view.qc +++ b/src/client/view.qc @@ -299,6 +299,7 @@ View_DrawViewModel(void) /* only draw the model when it's 'enabled'... */ if (m_eViewModel.IsHidden() == false) { + float oldModelindex; setorigin(m_eViewModel, m_eViewModel.origin); setorigin(m_eViewModelL, m_eViewModel.origin); @@ -323,21 +324,21 @@ View_DrawViewModel(void) /* TODO: clean this up. */ if (m_eViewModel.modelindex2) { - float oldModelindex = m_eViewModel.modelindex; + oldModelindex = m_eViewModel.modelindex; m_eViewModel.modelindex = m_eViewModel.modelindex2; addentity(m_eViewModel); m_eViewModel.modelindex = oldModelindex; } if (m_eViewModel.modelindex3) { - float oldModelindex = m_eViewModel.modelindex; + oldModelindex = m_eViewModel.modelindex; m_eViewModel.modelindex = m_eViewModel.modelindex3; addentity(m_eViewModel); m_eViewModel.modelindex = oldModelindex; } if (m_eViewModel.modelindex4) { - float oldModelindex = m_eViewModel.modelindex; + oldModelindex = m_eViewModel.modelindex; m_eViewModel.modelindex = m_eViewModel.modelindex4; addentity(m_eViewModel); m_eViewModel.modelindex = oldModelindex; diff --git a/src/cvar_defaults.cfg b/src/cvar_defaults.cfg new file mode 100644 index 00000000..df3a6f48 --- /dev/null +++ b/src/cvar_defaults.cfg @@ -0,0 +1,185 @@ +// generated by Nuclide, do not modify +set _pext_infoblobs "1" // override +set _pext_vrinputs "0" // override +set _q3bsp_bihtraces "1" // override +set ai_debugAlerts "0" // Show prints when AI gets alerted to a position. +set ai_debugLogic "0" // Show prints when AI makes decisions regarding thinking. +set ai_debugNav "0" // Show prints when AI makes decisions regarding navigation. +set ai_debugScripts "0" // Show prints when AI interacts with scripted sequences. +set ai_enable "1" // Disable AI behaviour when set. +set ai_runSpeed "320" // Default run speed chosen by AI characters, in units per second. +set ai_walkSpeed "150" // Default walk speed chosen by AI characters, in units per second. +set bot_aimless "0" // Bots will not set goals for themselves when set. +set bot_backspeed "133" // Bots desired maximum backwards speed. +set bot_crouch "0" // Bots are all forced to move crouched. +set bot_developer "0" // TODO: remove? +set bot_dont_shoot "0" // Bots never actually shoot. +set bot_enable "1" // Bot support enabled when set. +set bot_fastChat "0" // Bots will chat instantly instead of 'typing'. +set bot_forwardspeed "190" // Bots desired maximum forward speed. +set bot_minClients "-1" // How many player slots are to be filled, -1 is 'untouched'. +set bot_noChat "0" // Bots will no longer communicate when set. +set bot_pause "0" // Bots logic will be paused. +set bot_prefix "" // Bot nickname prefix for newly added bots. +set bot_prone "0" // Bots are all forced to move prone. +set bot_sidespeed "152" // Bots desired maximum strafe speed. +set bot_skill "2" // Bot version of cvar "skill". +set bot_walk "0" // Bots are forced to walk slowly. +set cfg_save_auto "1" // override +set cg_chatEnabled "1" // Enable the display of chat messages. +set cg_damageShake "0" // Shake the display upon taking damage. +set cg_hudAspect "0" // Aspect ratio override for the HUD. 1.0 is 1:1 square, 0 is auto. +set cg_modelBobHeight "0.0" // Intensity at which objects with the "spin" flag bob. +set cg_modelBobHeightSpeed "0.0" // Speed at which objects with the "spin" flag bob. +set cg_modelSpinPitch "0.0" // Intensity at which objects with the "spin" flag change their pitch. +set cg_modelSpinPitchSpeed "0.0" // Speed at which objects with the "spin" flag change their pitch. +set cg_modelSpinRoll "0.0" // Intensity at which objects with the "spin" flag roll. +set cg_modelSpinRollSpeed "0.0" // Speed at which objects with the "spin" flag roll. +set cg_modelSpinSpeed "120.0" // Speed at which an object with the "spin" key spins. +set cg_muzzleDLight "1" // Enable dlights being spawned from muzzleflashes. +set cg_muzzleDLightColor "1.0 0.45 0.0" // Color of muzzleflash dlights. +set cg_viewZSmoothingMax "16" // Camera vertical-axis smoothing max delta threshold. +set cg_viewZSmoothingMin "1" // Camera vertical-axis smoothing delta threshold. +set cg_viewZSmoothingTime "0.1" // Camera vertical-axis smoothing steps. +set cg_viewmodelFlip "0" // Flip the viewmodel. +set cg_viewmodelFov "90" // Viewmodel field of view. +set cg_viewmodelLag "0" // Viewmodel lag when camera looks around. +set cg_viewmodelOffset "0 0 0" // Viewmodel offset in relative units (forward, right, up) +set cg_viewmodelPass "1" // Renders viewmodel in separate drawpass (no lighting) +set cg_viewmodelScale "1.0" // Viewmodel scale multiplier, affects bob as well. +set cl_backspeed "400" // Client's desired backwards speed. +set cl_bob "0" // override +set cl_cursor_scale "1" // override +set cl_decals "128" // override +set cl_forwardspeed "400" // Client's desired forward speed. +set cl_musicstyle "0" // override +set cl_sidespeed "400" // Client's desired side-step speed. +set con_color "255 150 0" // HUD color value, R G B, 0-255 for each channel. +set con_notifylines "0" // override +set dev_cornerspeed "0" // Override speed set by path_corner entities. +set dev_loddistance "0" // Override distance at which func_lod entities disappear. +set dev_skyscale "" // Override for the sky_camera room scale. +set dsp_soundscapes "1" // Enable the use of sound scapes. +set g_damageScale "1" // final damage scale on objects +set g_gravity "800" // Global gravity setting. +set g_logLevel "2" // Game console log levels. 0 = None, 1 = Errors, 2 = Warnings, 3 = Extra Messages +set g_logTimestamps "0" // When 1, will print time stamps before the log message +set gl_conback "gfx/devcon" // override +set gl_mindist "4" // override +set gl_blendsprites "0" // override +set gl_specular "1" // override +set gl_specular_fallback "0" // override +set in_zoomSensitivity "1.0" // Input sensitivity multiplier for when you're zoomed in. +set logging_enabled "0" // Enable server-side logging for game specific events. +set maxpitch "89" // override +set menu_helptext_size "11" +set menu_intro "1" +set menu_steambg "0" +set menu_updating "0" +set media_repeat "0" // override +set minpitch "-89" // override +set motdfile "motd.txt" +set mp_allowvote "1" +set mp_decals "128" +set mp_flashlight "1" +set mp_td_dmgToKick "300" +set mp_td_dmgToWarn "200" +set nav_linksize "256" +set nav_radius "32" +set phys_developer "0" // Shows debug prints regarding physics operations when set. +set phys_impactforcescale "100" // Scaler for impact forces on physically simulated entities. +set phys_pushscale "1" // Scaler for push forces on physically simulated entities. +set pm_accelerate "10" +set pm_airaccelerate "10" +set pm_airstepsize "0" +set pm_boxcenter "1" +set pm_boxwidth "32" +set pm_crouchheight "36" +set pm_crouchspeed "90" +set pm_crouchviewheight "30" +set pm_edgefriction "1" +set pm_friction "4" +set pm_gravity "800" +set pm_jumpheight "265" +set pm_maxviewpitch "89" +set pm_minviewpitch "-89" +set pm_noclipaccelerate "5" +set pm_noclipspeed "500" +set pm_normalheight "72" +set pm_normalviewheight "64" +set pm_nospeedcap "0" +set pm_proneheight "0" +set pm_pronespeed "40.5" +set pm_proneviewheight "16" +set pm_runspeed "0" +set pm_stairSmoothing "1" +set pm_stamina "24" +set pm_staminarate "0.75" +set pm_staminathreshold "4" +set pm_stepsize "18" +set pm_stopspeed "100" +set pm_thirdPerson "0" +set pm_walkspeed "270" +set pm_wateraccelerate "10" +set pm_waterjumpheight "350" +set r_autoscale "1" // When set, will ensure the game is at 640x480 type scaling. +set r_drawdecals "1" // Shows decal entities managed by the game when set. +set r_ignoreentpvs "0" // override +set r_imageextensions "tga bmp pcx png jpg" // override +set r_meshpitch "1" // override +set r_pixelscale "0" // When set, will ensure the 3D rendered scene is restricted to 640x480 resolution in definition. +set r_renderEntityInfo "0" // Display visual information about entities in-world. +set r_showDlights "0" // Displays dynamic light representations in-world. +set r_showPhysicsInfo "0" // Displays physics entity information in-world. +set r_skipGlows "0" // Skip rendering of glowing sprites. +set r_skipLensFlares "0" // Skip rendering of lens flares. +set r_skipWorld "0" // Skip rendering of the world. +set rm_unlit_additive "1" // Render entities with the 'additive' rendermode fullbright. +set rm_unlit_texture "1" // Render entities with the 'texture' rendermode fullbright. +set rope_debug "0" // Shows primitive debug rendering of a rope when set. +set rope_fast "1" // Don't perform expensive calculations on the rope when set. +set rope_maxsegments "-1" // Limit rope segments. -1 means no limit. +set rope_sag "2" // Rope sagging multiplier. +set rope_swing "2" // Rope swinging multiplier. +set s_logLevel "2" // Sound console log levels. 0 = None, 1 = Errors, 2 = Warnings, 3 = Extra Messages +set scr_conalpha "1" // override +set sp_decals "128" +set sv_friendlyFire "0" // Team-inflicted damage is possible when set. +set sv_gameplayfix_setmodelrealbox "1" // override +set sv_gameplayfix_setmodelsize_qw "1" // override +set sv_levelexec "1" // Will search and execute `/maps/currentmap.cfg` when set. +set sv_plugins "1" // Enable the use of server-side plugins when set. +set v_contentblend "0" // override +set vehicle_developer "0" // Shows vehicle related debug prints when set. +set vgui_color "255 170 0" // Default primary color for VGUI widgets. +set vid_brightness "0" // Controls display brightness. +set violence_ablood "1" // Enable non-human (alternative) blood. +set violence_agibs "1" // Enable non-human (alternative) gibs. +set violence_hblood "1" // Enable human blood. +set violence_hgibs "1" // Enable human giblets. +set xr_roomScale "1.0" // XR: Room scale multiplier. +set xr_testInputs "0" // XR: Enable fake inputs, to debug the VR camera and weapon inputs. +set xr_viewHeight "-48" // XR: Default view-height offset. +set physics_ode_quadtree_depth "5" // override +set physics_ode_contactsurfacelayer "0" // override +set physics_ode_worldquickstep "1" // override +set physics_ode_worldquickstep_iterations "20" // override +set physics_ode_contact_mu "1" // override +set physics_ode_contact_erp "0.96" // override +set physics_ode_contact_cfm "0.001" // override +set physics_ode_world_damping "-1" // override +set physics_ode_world_damping_linear "-1" // override +set physics_ode_world_damping_linear_threshold "-1" // override +set physics_ode_world_damping_angular "-1" // override +set physics_ode_world_damping_angular_threshold "-1" // override +set physics_ode_world_erp "0.96" // override +set physics_ode_world_cfm "0.001" // override +set physics_ode_iterationsperframe "1" // override +set physics_ode_movelimit "2.0" // override +set physics_ode_spinlimit "10000" // override +set physics_ode_autodisable "1" // override +set physics_ode_autodisable_steps "10" // override +set physics_ode_autodisable_time "0.1" // override +set physics_ode_autodisable_threshold_linear "0.05" // Was 0.2, too lenient. +set physics_ode_autodisable_threshold_angular "0.3" // override +set physics_ode_autodisable_threshold_samples "5" // override diff --git a/src/gs-entbase/client/func_smokevolume.qc b/src/gs-entbase/client/func_smokevolume.qc index d45368af..39b4f358 100644 --- a/src/gs-entbase/client/func_smokevolume.qc +++ b/src/gs-entbase/client/func_smokevolume.qc @@ -82,6 +82,7 @@ float func_smokevolume_cloud::predraw(void) { float alpha; + vector color = m_vecColor; vector vecPlayer = g_view.GetCameraOrigin(); if (checkpvs(vecPlayer, this) == FALSE) { @@ -99,17 +100,17 @@ func_smokevolume_cloud::predraw(void) alpha *= m_flMaxAlpha; if (!(spawnflags & 1)) { - m_vecColor *= (getlight(origin) / 255); - m_vecColor[0] = bound(0.0, m_vecColor[0], 1.0); - m_vecColor[1] = bound(0.0, m_vecColor[1], 1.0); - m_vecColor[2] = bound(0.0, m_vecColor[2], 1.0); + color *= (getlight(origin) / 255); + color[0] = bound(0.0, color[0], 1.0); + color[1] = bound(0.0, color[1], 1.0); + color[2] = bound(0.0, color[2], 1.0); } R_BeginPolygon(m_strMaterial, 0, 0); - R_PolygonVertex(origin + v_right * cloudsize[0] - v_up * cloudsize[1], [1,1], m_vecColor, alpha); - R_PolygonVertex(origin - v_right * cloudsize[0] - v_up * cloudsize[1], [0,1], m_vecColor, alpha); - R_PolygonVertex(origin - v_right * cloudsize[0] + v_up * cloudsize[1], [0,0], m_vecColor, alpha); - R_PolygonVertex(origin + v_right * cloudsize[0] + v_up * cloudsize[1], [1,0], m_vecColor, alpha); + R_PolygonVertex(origin + v_right * cloudsize[0] - v_up * cloudsize[1], [1,1], color, alpha); + R_PolygonVertex(origin - v_right * cloudsize[0] - v_up * cloudsize[1], [0,1], color, alpha); + R_PolygonVertex(origin - v_right * cloudsize[0] + v_up * cloudsize[1], [0,0], color, alpha); + R_PolygonVertex(origin + v_right * cloudsize[0] + v_up * cloudsize[1], [1,0], color, alpha); R_EndPolygon(); if (lifetime >= 10.0f) { @@ -135,16 +136,18 @@ float func_smokevolume::predraw(void) { vector vecPlayer = g_view.GetCameraOrigin(); - float playerDist = vlen(vecPlayer - origin); - float fracDist = 1.0 - bound(0.0, playerDist / 512, 1.0); if (checkpvs(vecPlayer, this) == FALSE) return (PREDRAW_NEXT); + float playerDist = distance(vecPlayer, WorldSpaceCenter()); + if (m_flMaxDrawDistance > 0.0) if (playerDist > m_flMaxDrawDistance) return (PREDRAW_NEXT); + float fracDist = 1.0f - bound(0.0f, playerDist / m_flMaxDrawDistance, 1.0f); + if (m_flNexTime > cltime) return (PREDRAW_NEXT); @@ -158,7 +161,12 @@ func_smokevolume::predraw(void) setorigin(cloud, vecPos); float r = random(); cloud.m_vecColor = vectorLerp(m_vecColor1, m_vecColor2, r); - cloud.m_flMaxAlpha = m_flAlpha * fracDist; + + if (m_flMaxDrawDistance > 0.0f) + cloud.m_flMaxAlpha = m_flAlpha * fracDist; + else + cloud.m_flMaxAlpha = m_flAlpha; + cloud.cloudsize[0] = random(m_flSizeMin, m_flSizeMax); cloud.cloudsize[1] = random(m_flSizeMin, m_flSizeMax); cloud.m_flLifeTime = random(m_flLifetimeMin, m_flLifetimeMax); @@ -229,8 +237,9 @@ func_smokevolume::func_smokevolume(void) m_flSizeMax = 250; m_flLifetimeMin = 3; m_flLifetimeMax = 5; - m_flAlpha = 1.0f; + m_flAlpha = 0.1f; /* making this up, I have no idea */ m_vecColor1 = m_vecColor2 = [0,0,0]; + m_flMaxDrawDistance = 0.0f; solid = SOLID_NOT; isCSQC = true; diff --git a/src/gs-entbase/server.src b/src/gs-entbase/server.src index e63fa4f7..830c9a50 100644 --- a/src/gs-entbase/server.src +++ b/src/gs-entbase/server.src @@ -90,6 +90,7 @@ server/point_camera.qc server/point_servercommand.qc server/point_trigger.qc server/targ_speaker.qc +server/target_speaker.qc server/target_cdaudio.qc server/env_global.qc server/script_model.qc diff --git a/src/gs-entbase/server/env_explosion.qc b/src/gs-entbase/server/env_explosion.qc index 5b30b037..40a67eac 100644 --- a/src/gs-entbase/server/env_explosion.qc +++ b/src/gs-entbase/server/env_explosion.qc @@ -198,7 +198,7 @@ env_explosion::Trigger(entity act, triggermode_t state) damageType = DMG_GENERIC; } - radiusDamage(GetOrigin(), GetExplosionRadius(), 0i, GetExplosionDamage(), act, ""); + combat.RadiusDamage(GetOrigin(), GetExplosionRadius(), 0i, GetExplosionDamage(), act, ""); } if (HasSpawnFlags(ENVEXPLO_REPEATABLE) == false) { diff --git a/src/gs-entbase/server/func_breakable.qc b/src/gs-entbase/server/func_breakable.qc index e6866b0f..982c9d1c 100644 --- a/src/gs-entbase/server/func_breakable.qc +++ b/src/gs-entbase/server/func_breakable.qc @@ -310,7 +310,7 @@ func_breakable::Explode(void) BreakModel_Spawn(absmin, absmax, [0,0,0], m_flExplodeMag, vlen(size) / 10, breakModel); pointparticles(_m_iExplosionParticle, rp, [0,0,0], 1); - radiusDamage(GetOrigin(), m_flExplodeMag, 0i, m_flExplodeRad, this, ""); + combat.RadiusDamage(GetOrigin(), m_flExplodeMag, 0i, m_flExplodeRad, this, ""); UseTargets(this, TRIG_TOGGLE, 0.0f); /* delay... ignored. */ MakeInvulnerable(); Disappear(); diff --git a/src/gs-entbase/server/func_door.qc b/src/gs-entbase/server/func_door.qc index bb8c8e27..142f5d50 100644 --- a/src/gs-entbase/server/func_door.qc +++ b/src/gs-entbase/server/func_door.qc @@ -584,7 +584,7 @@ func_door::Blocked(entity eBlocker) NSDict damageDecl = spawn(NSDict); damageDecl.AddKey("damage", itos(m_iDamage)); m_bCanTouch = false; - entityDamage(eBlocker, this, eBlocker, damageDecl.GetDeclBody(), "", center, dmgDir, eBlocker.origin); + combat.Damage(eBlocker, this, eBlocker, damageDecl.GetDeclBody(), center, dmgDir, eBlocker.origin); remove(damageDecl); } diff --git a/src/gs-entbase/server/func_door_rotating.qc b/src/gs-entbase/server/func_door_rotating.qc index 534a83c6..099e8719 100644 --- a/src/gs-entbase/server/func_door_rotating.qc +++ b/src/gs-entbase/server/func_door_rotating.qc @@ -518,7 +518,7 @@ func_door_rotating::Blocked(entity eBlocker) NSDict damageDecl = spawn(NSDict); damageDecl.AddKey("damage", itos(m_iDamage)); m_bCanTouch = false; - entityDamage(eBlocker, this, eBlocker, damageDecl.GetDeclBody(), "", center, dmgDir, eBlocker.origin); + combat.Damage(eBlocker, this, eBlocker, damageDecl.GetDeclBody(), center, dmgDir, eBlocker.origin); remove(damageDecl); } diff --git a/src/gs-entbase/server/func_mortar_field.qc b/src/gs-entbase/server/func_mortar_field.qc index aa894298..572f2654 100644 --- a/src/gs-entbase/server/func_mortar_field.qc +++ b/src/gs-entbase/server/func_mortar_field.qc @@ -161,7 +161,7 @@ func_mortar_field::Fire(entity firingEnt, vector vecOrg) int maxDamage = 200i; float damageRadius = (float)maxDamage * 2.5f; - radiusDamage(trace_endpos, damageRadius, 0i, maxDamage, this, ""); + combat.RadiusDamage(trace_endpos, damageRadius, 0i, maxDamage, this, ""); pointparticles(particleeffectnum("fx_explosion.main"), trace_endpos, [0,0,0], 1); } diff --git a/src/gs-entbase/server/func_rotating.qc b/src/gs-entbase/server/func_rotating.qc index a3a78b12..279026f1 100644 --- a/src/gs-entbase/server/func_rotating.qc +++ b/src/gs-entbase/server/func_rotating.qc @@ -209,7 +209,7 @@ func_rotating::Blocked(entity eBlocker) vector dmgDir = dirFromTarget(center, eBlocker.origin); NSDict damageDecl = spawn(NSDict); damageDecl.AddKey("damage", ftos(m_flDamage)); - entityDamage(eBlocker, this, eBlocker, damageDecl.GetDeclBody(), "", center, dmgDir, eBlocker.origin); + combat.Damage(eBlocker, this, eBlocker, damageDecl.GetDeclBody(), center, dmgDir, eBlocker.origin); remove(damageDecl); } } diff --git a/src/gs-entbase/server/func_train.qc b/src/gs-entbase/server/func_train.qc index 7da8dbba..97796826 100644 --- a/src/gs-entbase/server/func_train.qc +++ b/src/gs-entbase/server/func_train.qc @@ -204,7 +204,7 @@ func_train::Blocked(entity eBlocker) dmgDir = dirFromTarget(center, eBlocker.origin); damageDecl = spawn(NSDict); damageDecl.AddKey("damage", "500"); - entityDamage(eBlocker, this, eBlocker, damageDecl.GetDeclBody(), "", center, dmgDir, eBlocker.origin); + combat.Damage(eBlocker, this, eBlocker, damageDecl.GetDeclBody(), center, dmgDir, eBlocker.origin); remove(damageDecl); return; } @@ -214,7 +214,7 @@ func_train::Blocked(entity eBlocker) dmgDir = dirFromTarget(center, eBlocker.origin); damageDecl = spawn(NSDict); damageDecl.AddKey("damage", ftos(m_flDamage)); - entityDamage(eBlocker, this, eBlocker, damageDecl.GetDeclBody(), "", center, dmgDir, eBlocker.origin); + combat.Damage(eBlocker, this, eBlocker, damageDecl.GetDeclBody(), center, dmgDir, eBlocker.origin); remove(damageDecl); } else { /* remove(eBlocker); */ diff --git a/src/gs-entbase/server/game_player_hurt.qc b/src/gs-entbase/server/game_player_hurt.qc index 860c0212..5fea0ec8 100644 --- a/src/gs-entbase/server/game_player_hurt.qc +++ b/src/gs-entbase/server/game_player_hurt.qc @@ -98,10 +98,10 @@ game_player_hurt::Trigger(entity activatingEntity, triggermode_t triggerMode) NSDict damageDecl = spawn(NSDict); damageDecl.AddKey("damage", itos(m_iDamage)); - entityDamage(activatingEntity, this, activatingEntity, damageDecl.GetDeclBody(), "", GetOrigin(), g_vec_null, activatingEntity.origin); + combat.Damage(activatingEntity, this, activatingEntity, damageDecl.GetDeclBody(), GetOrigin(), g_vec_null, activatingEntity.origin); remove(damageDecl); if (HasSpawnFlags(1)) { Destroy(); } -} \ No newline at end of file +} diff --git a/src/gs-entbase/server/game_player_team.qc b/src/gs-entbase/server/game_player_team.qc index d2882b53..6572f51c 100644 --- a/src/gs-entbase/server/game_player_team.qc +++ b/src/gs-entbase/server/game_player_team.qc @@ -74,17 +74,17 @@ game_player_team::Trigger(entity entityActivator, triggermode_t state) damageDecl = spawn(NSDict); damageDecl.AddKey("damage", ftos(targetPlayer.health + 100)); damageDecl.AddKey("skip_armor", "1"); - entityDamage(targetPlayer, this, targetPlayer, damageDecl.GetDeclBody(), "", GetOrigin(), g_vec_null, targetPlayer.origin); + combat.Damage(targetPlayer, this, targetPlayer, damageDecl.GetDeclBody(), GetOrigin(), g_vec_null, targetPlayer.origin); remove(damageDecl); } else if (HasSpawnFlags(2) == true) { damageDecl = spawn(NSDict); damageDecl.AddKey("damage", ftos(targetPlayer.health)); damageDecl.AddKey("skip_armor", "1"); - entityDamage(targetPlayer, this, targetPlayer, damageDecl.GetDeclBody(), "", GetOrigin(), g_vec_null, targetPlayer.origin); + combat.Damage(targetPlayer, this, targetPlayer, damageDecl.GetDeclBody(), GetOrigin(), g_vec_null, targetPlayer.origin); remove(damageDecl); } if (HasSpawnFlags(1)) { Destroy(); } -} \ No newline at end of file +} diff --git a/src/gs-entbase/server/light.qc b/src/gs-entbase/server/light.qc index b0e90aa0..22ba9972 100644 --- a/src/gs-entbase/server/light.qc +++ b/src/gs-entbase/server/light.qc @@ -260,11 +260,17 @@ void light::DebugDraw(void) { #ifdef SERVER - R_BeginPolygon(m_strDebugTexture, 0, 0); - R_PolygonVertex(GetOrigin() + v_right * 16 - v_up * 16, [1,1], _lightColor, 1.0f); - R_PolygonVertex(GetOrigin() - v_right * 16 - v_up * 16, [0,1], _lightColor, 1.0f); - R_PolygonVertex(GetOrigin() - v_right * 16 + v_up * 16, [0,0], _lightColor, 1.0f); - R_PolygonVertex(GetOrigin() + v_right * 16 + v_up * 16, [1,0], _lightColor, 1.0f); + if (m_iEnabled) { + m_strEditorIcon = "gfx/icon16/lightbulb"; + } else { + m_strEditorIcon = "gfx/icon16/lightbulb_off"; + } + + R_BeginPolygon(m_strEditorIcon, 0, 0); + R_PolygonVertex(GetOrigin() + v_right * 8 - v_up * 8, [1,1], _lightColor, 1.0f); + R_PolygonVertex(GetOrigin() - v_right * 8 - v_up * 8, [0,1], _lightColor, 1.0f); + R_PolygonVertex(GetOrigin() - v_right * 8 + v_up * 8, [0,0], _lightColor, 1.0f); + R_PolygonVertex(GetOrigin() + v_right * 8 + v_up * 8, [1,0], _lightColor, 1.0f); R_EndPolygon(); #endif } diff --git a/src/gs-entbase/server/point_camera.qc b/src/gs-entbase/server/point_camera.qc index 52c75de4..ebda5b8c 100644 --- a/src/gs-entbase/server/point_camera.qc +++ b/src/gs-entbase/server/point_camera.qc @@ -55,6 +55,7 @@ public: virtual void Restore(string,string); virtual void SpawnKey(string,string); virtual void Input(entity,string,string); + virtual void Respawn(void); private: int m_iUseSAR; @@ -142,6 +143,16 @@ point_camera::SpawnKey(string strKey, string strValue) } } +void +point_camera::Respawn(void) +{ + if (HasSpawnFlags(1)) { + m_iValue = false; + } else { + m_iValue = true; + } +} + void point_camera::Input(entity eAct, string strInput, string strData) { diff --git a/src/gs-entbase/server/targ_speaker.qc b/src/gs-entbase/server/targ_speaker.qc index dd43699e..487ec9ef 100644 --- a/src/gs-entbase/server/targ_speaker.qc +++ b/src/gs-entbase/server/targ_speaker.qc @@ -14,7 +14,7 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/*! \brief Server-Entity: Redundant Sound Emitter */ +/*! \brief Server-Entity: Redundant Sound Emitter #2 */ /*!QUAKED targ_speaker (1 0 0) (-8 -8 -8) (8 8 8) # OVERVIEW This entity plays a sample upon triggering at a specified volume. @@ -88,6 +88,7 @@ void targ_speaker::SpawnKey(string strKey, string strValue) { switch (strKey) { + case "noise": case "tsnoise": m_strSample = strValue; break; diff --git a/src/gs-entbase/server/target_speaker.qc b/src/gs-entbase/server/target_speaker.qc new file mode 100644 index 00000000..0cdae3ed --- /dev/null +++ b/src/gs-entbase/server/target_speaker.qc @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2016-2022 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +/*! \brief Server-Entity: Redundant Sound Emitter #1 */ +/*!QUAKED target_speaker (1 0 0) (-8 -8 -8) (8 8 8) +# OVERVIEW +This entity plays a background sound. + +# KEYS +- "targetname" : Name +- "target" : Target when triggered +- "killtarget" : Target to kill when triggered +- "noise" : Path to the sound file +- "volume" : Volume to play the sound as (normalized, 0.0 - 1.0) +- "attenuation" : Attenuation. -1 = everywhere, 1 = normal, 2 = ATTN_IDLE, 3 = ATTN_STATIC + +# SPAWNFLAGS +- LOOP (1) : Loop sound, always. + +# TRIVIA +It was introduced in Quake II (1997). + +@ingroup server +@ingroup pointentity +*/ +class +target_speaker:NSSound +{ +public: + void target_speaker(void); + + virtual void Respawn(void); + virtual void SpawnKey(string, string); +}; + +void +target_speaker::target_speaker(void) +{ +} + +void +target_speaker::SpawnKey(string keyName, string setValue) +{ + switch (keyName) { + case "noise": + SetSample(setValue); + case "volume": + float ourVolume = ReadFloat(setValue); + + if (ourVolume <= 0.0) { + ourVolume = 1.0f; + } + + SetVolume(ourVolume); + break; + default: + super::SpawnKey(keyName, setValue); + break; + } +} + +void +target_speaker::Respawn(void) +{ + if (HasSpawnFlags(1) == true) { + ForceLoop(true); + } +} diff --git a/src/gs-entbase/server/trigger_hurt.qc b/src/gs-entbase/server/trigger_hurt.qc index 92ddfe6a..71041f80 100644 --- a/src/gs-entbase/server/trigger_hurt.qc +++ b/src/gs-entbase/server/trigger_hurt.qc @@ -278,7 +278,7 @@ trigger_hurt::Touch(entity eToucher) NSDict damageDecl = spawn(NSDict); damageDecl.AddKey("damage", itos(m_iDamage)); damageDecl.AddKey("flags", itos(type)); - entityDamage(eToucher, this, eToucher, damageDecl.GetDeclBody(), "", center, g_vec_null, eToucher.origin); + combat.Damage(eToucher, this, eToucher, damageDecl.GetDeclBody(), center, g_vec_null, eToucher.origin); remove(damageDecl); /* shut it down if used once */ diff --git a/src/gs-entbase/shared.src b/src/gs-entbase/shared.src index 3a0c5018..141e148f 100644 --- a/src/gs-entbase/shared.src +++ b/src/gs-entbase/shared.src @@ -24,6 +24,7 @@ shared/logic_achievement.qc shared/func_monitor.qc shared/func_lod.qc shared/func_illusionary.qc +shared/func_useableladder.qc shared/func_ladder.qc shared/func_wall.qc shared/func_vehicle.qc diff --git a/src/gs-entbase/shared/ambient_generic.qc b/src/gs-entbase/shared/ambient_generic.qc index fa69f7a4..1ed39e6b 100644 --- a/src/gs-entbase/shared/ambient_generic.qc +++ b/src/gs-entbase/shared/ambient_generic.qc @@ -232,6 +232,8 @@ ambient_generic::Respawn(void) super::Respawn(); SetSize([0,0,0], [0,0,0]); + SetSolid(SOLID_NOT); + SetMovetype(MOVETYPE_NONE); m_strActivePath = m_strSpawnPath; m_flPitch = m_flSpawnPitch; @@ -274,6 +276,8 @@ ambient_generic::Respawn(void) Trigger = UseLoop; } + + customphysics = __NULL__; } void @@ -385,27 +389,23 @@ ambient_generic::SendEntity(entity ePEnt, float flChanged) WriteFloat(MSG_ENTITY, flChanged); - if (flChanged & AMBIENT_ORIGIN) { - WriteCoord(MSG_ENTITY, origin[0]); - WriteCoord(MSG_ENTITY, origin[1]); - WriteCoord(MSG_ENTITY, origin[2]); - } - + SENDENTITY_COORD(origin[0], AMBIENT_ORIGIN) + SENDENTITY_COORD(origin[1], AMBIENT_ORIGIN) + SENDENTITY_COORD(origin[2], AMBIENT_ORIGIN) + if (flChanged & AMBIENT_PATH) { if (flChanged & AMBIENT_MODERN) { - WriteString(MSG_ENTITY, m_strActivePath); + SENDENTITY_STRING(m_strActivePath, AMBIENT_PATH) } else { WriteFloat(MSG_ENTITY, getsoundindex(m_strActivePath, true)); + m_strActivePath_net = m_strActivePath; } } - if (flChanged & AMBIENT_VOLUME) - WriteFloat(MSG_ENTITY, m_flVolume); - if (flChanged & AMBIENT_RADIUS) - WriteByte(MSG_ENTITY, m_flRadius); - if (flChanged & AMBIENT_PITCH) - WriteFloat(MSG_ENTITY, m_flPitch); - if (flChanged & AMBIENT_ENABLED) - WriteByte(MSG_ENTITY, m_bLoops); + + SENDENTITY_FLOAT(m_flVolume, AMBIENT_VOLUME) + SENDENTITY_BYTE(m_flRadius, AMBIENT_RADIUS) + SENDENTITY_FLOAT(m_flPitch, AMBIENT_PITCH) + SENDENTITY_BYTE(m_bLoops, AMBIENT_ENABLED) return (1); } @@ -414,6 +414,7 @@ void ambient_generic::ReceiveEntity(float isnew, float flChanged) { if (flChanged & AMBIENT_ORIGIN) { + vector oldOrg = origin; origin[0] = readcoord(); origin[1] = readcoord(); origin[2] = readcoord(); diff --git a/src/gs-entbase/shared/env_beam.qc b/src/gs-entbase/shared/env_beam.qc index 7646ae70..cea9dce9 100644 --- a/src/gs-entbase/shared/env_beam.qc +++ b/src/gs-entbase/shared/env_beam.qc @@ -211,7 +211,7 @@ env_beam::CastLaser(void) damageDecl.AddKey("damage", itos(m_iDamage)); damageDecl.AddKey("type", "electro"); - entityDamage(trace_ent, this, trace_ent, damageDecl.GetDeclBody(), "", center, g_vec_null, trace_ent.origin); + combat.Damage(trace_ent, this, trace_ent, damageDecl.GetDeclBody(), center, g_vec_null, trace_ent.origin); remove(damageDecl); } diff --git a/src/gs-entbase/shared/env_glow.qc b/src/gs-entbase/shared/env_glow.qc index efe83384..0297b78a 100644 --- a/src/gs-entbase/shared/env_glow.qc +++ b/src/gs-entbase/shared/env_glow.qc @@ -346,6 +346,7 @@ env_glow::ReceiveEntity(float flNew, float flChanged) if (flNew) RendererRestarted(); + effects = EF_NODEPTHTEST; drawmask = MASK_GLOWS; setsize(this, g_vec_null, g_vec_null); setorigin(this, origin); diff --git a/src/gs-entbase/shared/env_laser.qc b/src/gs-entbase/shared/env_laser.qc index a1664d61..4db47616 100644 --- a/src/gs-entbase/shared/env_laser.qc +++ b/src/gs-entbase/shared/env_laser.qc @@ -179,7 +179,7 @@ env_laser::CastLaser(void) damageDecl.AddKey("damage", itos(m_iDamage)); damageDecl.AddKey("type", "electro"); - entityDamage(trace_ent, this, trace_ent, damageDecl.GetDeclBody(), "", center, g_vec_null, trace_ent.origin); + combat.Damage(trace_ent, this, trace_ent, damageDecl.GetDeclBody(), center, g_vec_null, trace_ent.origin); remove(damageDecl); m_flTraceTime = time + 1.0f; } diff --git a/src/gs-entbase/shared/env_sprite.qc b/src/gs-entbase/shared/env_sprite.qc index c185d687..e4ec929c 100644 --- a/src/gs-entbase/shared/env_sprite.qc +++ b/src/gs-entbase/shared/env_sprite.qc @@ -78,6 +78,7 @@ public: virtual float SendEntity(entity,float); virtual void SpawnKey(string,string); virtual void NetworkOnce(void); + virtual void Respawn(void); #else virtual float predraw(void); virtual void think(void); @@ -142,7 +143,7 @@ env_sprite::SendEntity(entity ePEnt, float flChanged) return (0); /* strings are expensive. */ - if (!m_strMaterial) + if (!STRING_SET(m_strMaterial)) flChanged &= ~SPRITE_CHANGED_MATERIAL; WriteByte(MSG_ENTITY, ENT_SPRITE); @@ -173,7 +174,12 @@ env_sprite::NetworkOnce(void) WriteCoord(MSG_MULTICAST, origin[0]); WriteCoord(MSG_MULTICAST, origin[1]); WriteCoord(MSG_MULTICAST, origin[2]); - WriteFloat(MSG_MULTICAST, modelindex); + + if (STRING_SET(m_strMaterial)) + WriteFloat(MSG_MULTICAST, 0); + else + WriteFloat(MSG_MULTICAST, modelindex); + WriteFloat(MSG_MULTICAST, m_flFramerate); WriteFloat(MSG_MULTICAST, scale); WriteByte(MSG_MULTICAST, m_iRenderMode); @@ -227,6 +233,26 @@ env_sprite::Spawned(void) if (!targetname) m_iToggled = TRUE; } + +void +env_sprite::Respawn(void) +{ + super::Respawn(); + + string modelTest = GetSpawnString("model"); + + /* HACK: Source Engine support. Yes, they re-used 'model' for this. */ + if (exists.InVFS(modelTest) == false) { + + string sourceVMT = strcat("materials/", Util_ChangeExtension(modelTest, "vmt")); + + if (exists.InVFS(sourceVMT)) { + m_strMaterial = sourceVMT; + model = __NULL__; + modelindex = 0; + } + } +} #else float env_sprite::predraw(void) @@ -246,6 +272,8 @@ env_sprite::predraw(void) traceline(origin, vecPlayer, MOVE_WORLDONLY, this); + trace_fraction = 1.0f; + if (trace_fraction < 1.0) return (PREDRAW_NEXT); @@ -299,6 +327,7 @@ env_sprite::ReceiveEntity(float flNew, float flChanged) READENTITY_BYTE(m_flRenderAmt, SPRITE_CHANGED_RENDERAMT) READENTITY_STRING(m_strMaterial, SPRITE_CHANGED_MATERIAL) + effects = EF_NODEPTHTEST; drawmask = MASK_ENGINE; nextthink = time + (1 / m_flFramerate); m_iMaxFrame = modelframecount(modelindex); diff --git a/src/gs-entbase/shared/func_ladder.qc b/src/gs-entbase/shared/func_ladder.qc index 97ee7b9a..0c1872b2 100644 --- a/src/gs-entbase/shared/func_ladder.qc +++ b/src/gs-entbase/shared/func_ladder.qc @@ -42,6 +42,11 @@ public: }; +void +func_ladder::func_ladder(void) +{ +} + #ifdef SERVER void func_ladder::Trigger(entity act, triggermode_t state) @@ -66,13 +71,8 @@ func_ladder::Respawn(void) /* func_ladder specifics */ SetMovetype(MOVETYPE_NONE); - SetSolid(SOLID_BSP); - SetSkin(CONTENT_LADDER); SetFrame(0); Hide(); -} - -void -func_ladder::func_ladder(void) -{ + SetSolid(SOLID_BSP); + SetSkin(CONTENT_LADDER); } diff --git a/src/gs-entbase/shared/func_monitor.qc b/src/gs-entbase/shared/func_monitor.qc index 6c5e7855..802626a1 100644 --- a/src/gs-entbase/shared/func_monitor.qc +++ b/src/gs-entbase/shared/func_monitor.qc @@ -24,22 +24,23 @@ vector g_vecRenderTargetAngles; void RenderTarget_Monitor_Update(void) { - if (!g_iRenderTargetActive) { + if (g_iRenderTargetActive == false) { return; } clearscene(); - setviewprop(VF_RT_DESTCOLOUR, "base", (float)1, g_iRenderTargetSize); - setviewprop(VF_SIZE, g_iRenderTargetSize); - setviewprop(VF_DRAWENGINESBAR, (float)0); - setviewprop(VF_ORIGIN, g_vecRenderTargetPos); - setviewprop(VF_ANGLES, g_vecRenderTargetAngles); - setviewprop(VF_AFOV, g_flRenderTargetFOV); /* TODO: This is ideally where fog parms should be set... :/ */ addentities(MASK_ENGINE); + + setproperty(VF_RT_DESTCOLOUR, "base", (float)1, g_iRenderTargetSize); + setproperty(VF_SIZE, g_iRenderTargetSize); + setproperty(VF_DRAWENGINESBAR, (float)0); + setproperty(VF_ORIGIN, g_vecRenderTargetPos); + setproperty(VF_ANGLES, g_vecRenderTargetAngles); + setproperty(VF_AFOV, g_flRenderTargetFOV); renderscene(); - setviewprop(VF_RT_DESTCOLOUR, ""); + setproperty(VF_RT_DESTCOLOUR, ""); } #endif @@ -183,32 +184,40 @@ func_monitor::SendEntity(entity ePEnt, float flChanged) void func_monitor::EvaluateEntity(void) { - if (ATTR_CHANGED(origin)) { - SetSendFlags(MONITORFL_CHANGED_BASE); - } - SAVE_STATE(origin) + point_camera viewPoint; /* this monitor is disabled */ - if (!m_bState) + if (!m_bState) { return; + } - point_camera viewer; - viewer = (point_camera)find(world, ::targetname, target); - - if (!viewer) + /* no target set. yet. */ + if (!STRING_SET(target)) { + m_bState = false; return; + } - m_vecCamOrigin = viewer.origin; - m_vecCamAngles = viewer.angles; - m_flFOV = viewer.m_flFOV; - m_iUseSAR = viewer.m_iUseSAR; - m_vecFogColor = viewer.m_vecFogColor; - m_flFogStart = viewer.m_flFogStart; - m_bState = viewer.m_iValue ? true : false; + viewPoint = (point_camera)find(world, ::targetname, target); + + /* target set, but invalid. */ + if (!viewPoint) { + EntError("No valid target %S in map.", target); + Destroy(); + return; + } + + m_vecCamOrigin = viewPoint.origin; + m_vecCamAngles = viewPoint.angles; + m_flFOV = viewPoint.m_flFOV; + m_iUseSAR = viewPoint.m_iUseSAR; + m_vecFogColor = viewPoint.m_vecFogColor; + m_flFogStart = viewPoint.m_flFogStart; + m_bState = viewPoint.m_iValue ? true : false; /* camera is disabled */ - if (!viewer.m_iValue) + if (!viewPoint.m_iValue) { return; + } EVALUATE_FIELD(modelindex, MONITORFL_CHANGED_BASE) EVALUATE_VECTOR(origin, 0, MONITORFL_CHANGED_BASE) diff --git a/src/gs-entbase/shared/func_tankmortar.qc b/src/gs-entbase/shared/func_tankmortar.qc index 577225fa..c81b9328 100644 --- a/src/gs-entbase/shared/func_tankmortar.qc +++ b/src/gs-entbase/shared/func_tankmortar.qc @@ -348,7 +348,7 @@ func_tankmortar::PlayerInput(void) traceline(spos, spos + (dir * 4096), MOVE_NORMAL, this); damageRange = (float)m_iDamage * 2.5f; - radiusDamage(trace_endpos, damageRange, 0i, m_iDamage, m_eDriver, ""); + combat.RadiusDamage(trace_endpos, damageRange, 0i, m_iDamage, m_eDriver, ""); /* fx */ pointparticles(particleeffectnum("fx_explosion.main"), trace_endpos, [0,0,0], 1); diff --git a/src/gs-entbase/shared/func_useableladder.qc b/src/gs-entbase/shared/func_useableladder.qc new file mode 100644 index 00000000..ef0884e8 --- /dev/null +++ b/src/gs-entbase/shared/func_useableladder.qc @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2016-2022 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +/*! \brief Shared-Entity: Ladder Volume */ +/*!QUAKED func_useableladder (0 .5 .8) ? +# OVERVIEW +Ladder volume. Climb up ladders with this one simple brush. + +# KEYS +- "targetname" : Name + +# TRIVIA +This entity was introduced in Half-Life 2 (2004). + +@ingroup shared +@ingroup brushentity +*/ +class +func_useableladder:NSRenderableEntity +{ +public: + void func_useableladder(void); + + virtual void SpawnKey(string, string); + virtual void Respawn(void); + +#ifdef SERVER + virtual void Trigger(entity, triggermode_t); +#endif + +private: + vector m_vecPoint0; + vector m_vecPoint1; +}; + +void +func_useableladder::func_useableladder(void) +{ +} + +void +func_useableladder::SpawnKey(string keyName, string setValue) +{ + switch (keyName) { + case "point0": + m_vecPoint0 = ReadVector(setValue); + break; + case "point1": + m_vecPoint1 = ReadVector(setValue); + break; + default: + super::SpawnKey(keyName, setValue); + } +} + +#ifdef SERVER +void +func_useableladder::Trigger(entity act, triggermode_t state) +{ + switch (state) { + case TRIG_OFF: + SetSolid(SOLID_NOT); + break; + case TRIG_ON: + SetSolid(SOLID_BBOX); + break; + default: + m_bEnabled = 1 - m_bEnabled; + SetSolid((m_bEnabled) ? SOLID_BBOX : SOLID_NOT); + } +} +#endif + +void +func_useableladder::Respawn(void) +{ + float height; + + if (m_vecPoint0[2] > m_vecPoint1[2]) { + SetOrigin(m_vecPoint1); + height = m_vecPoint0[2] - m_vecPoint1[2]; + } else { + SetOrigin(m_vecPoint0); + height = m_vecPoint1[2] - m_vecPoint0[2]; + } + + /* func_useableladder specifics */ + SetSize([-16,-16, 0], [16,16, height]); + SetMovetype(MOVETYPE_NONE); + Hide(); + SetSolid(SOLID_BBOX); + SetSkin(CONTENT_LADDER); +} diff --git a/src/gs-entbase/shared/phys_rope.qc b/src/gs-entbase/shared/phys_rope.qc index 13f03c25..abb5f760 100644 --- a/src/gs-entbase/shared/phys_rope.qc +++ b/src/gs-entbase/shared/phys_rope.qc @@ -194,6 +194,7 @@ phys_rope::EvaluateEntity(void) if (!eFind) { EntError("phys_rope: Unable to find target %S", target); + Destroy(); return; } @@ -352,4 +353,4 @@ phys_rope::phys_rope(void) } CLASSEXPORT(move_rope, phys_rope) -CLASSEXPORT(keyframe_rope, phys_rope) \ No newline at end of file +CLASSEXPORT(keyframe_rope, phys_rope) diff --git a/src/gs-entbase/shared/prop_vehicle_driveable.qc b/src/gs-entbase/shared/prop_vehicle_driveable.qc index db2ab688..78c225c9 100644 --- a/src/gs-entbase/shared/prop_vehicle_driveable.qc +++ b/src/gs-entbase/shared/prop_vehicle_driveable.qc @@ -1,45 +1,45 @@ -/* - * Copyright (c) 2016-2022 Vera Visions LLC. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ +/* + * Copyright (c) 2016-2022 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + + +#define VEH_SKIDDING VFL_USE_RELEASED + +#define VEHSF_NOFLIP 2048 + +enumflags +{ + VEHFL_DRIVER, + VEHFL_MODELINDEX, + VEHFL_ORIGIN, + VEHFL_ANGLES, + VEHFL_VELOCITY, + VEHFL_TURNING, + VEHFL_FLAGS +}; - -#define VEH_SKIDDING VFL_USE_RELEASED - -#define VEHSF_NOFLIP 2048 - -enumflags -{ - VEHFL_DRIVER, - VEHFL_MODELINDEX, - VEHFL_ORIGIN, - VEHFL_ANGLES, - VEHFL_VELOCITY, - VEHFL_TURNING, - VEHFL_FLAGS -}; - static class -prop_vehicle_driveable_wheel -{ +prop_vehicle_driveable_wheel:NSIO +{ public: - void prop_vehicle_driveable_wheel(void); - -#ifdef CLIENT + void prop_vehicle_driveable_wheel(void); + +#ifdef CLIENT virtual void PredictPreFrame(void); virtual void PredictPostFrame(void); -#endif +#endif virtual void UpdateSuspension(float); virtual void Move(float); @@ -48,72 +48,74 @@ public: virtual void Physics(float,float); private: - float m_flSuspension; - float m_flSuspensionForce; - -#ifdef CLIENT - vector origin_net; - vector velocity_net; - vector angles_net; -#endif -}; - + float m_flSuspension; + float m_flSuspensionForce; + +#ifdef CLIENT + vector origin_net; + vector velocity_net; + vector angles_net; +#endif +}; + /*! \brief Shared-Entity: Model Based Vehicle */ -/*!QUAKED prop_vehicle_driveable (1 0 0) (-50 -50 0) (50 50 70) +/*!QUAKED prop_vehicle_driveable (1 0 0) (-50 -50 0) (50 50 70) # OVERVIEW -Point entity defining a 4-wheel vehicle that you can drive. - -# KEYS -- "targetname" : Name - -# SPAWNFLAGS - None currently. - -# NOTES - None currently. - -# TRIVIA -This entity was introduced in Half-Life 2 (2004). +Point entity defining a 4-wheel vehicle that you can drive. + +# KEYS +- "targetname" : Name + +# SPAWNFLAGS + +None currently. + +# NOTES + +None currently. + +# TRIVIA +This entity was introduced in Half-Life 2 (2004). @ingroup shared @ingroup pointentity -*/ -class prop_vehicle_driveable:NSVehicle -{ +*/ +class prop_vehicle_driveable:NSVehicle +{ private: - /* map-entity fields */ - float m_flBounceFactor; - float m_flAcceleration; - float m_flSkidSpeed; - float m_flTraction; - float m_flBreakFactor; - float m_flSteerFactor; - float m_flStraightenFactor; - vector m_vecGravityDir; - float m_flTimeLength; - vector m_vecSeatOffest; - - /* collision boxes */ - NSEntity m_eCollBox1; - NSEntity m_eCollBox2; - - prop_vehicle_driveable_wheel m_wlFL; - prop_vehicle_driveable_wheel m_wlFR; - prop_vehicle_driveable_wheel m_wlBL; - prop_vehicle_driveable_wheel m_wlBR; - vector m_vecControlMins; - vector m_vecControlMaxs; + /* map-entity fields */ + float m_flBounceFactor; + float m_flAcceleration; + float m_flSkidSpeed; + float m_flTraction; + float m_flBreakFactor; + float m_flSteerFactor; + float m_flStraightenFactor; + vector m_vecGravityDir; + float m_flTimeLength; + vector m_vecSeatOffest; + + /* collision boxes */ + NSEntity m_eCollBox1; + NSEntity m_eCollBox2; + + prop_vehicle_driveable_wheel m_wlFL; + prop_vehicle_driveable_wheel m_wlFR; + prop_vehicle_driveable_wheel m_wlBL; + prop_vehicle_driveable_wheel m_wlBR; + vector m_vecControlMins; + vector m_vecControlMaxs; PREDICTED_FLOAT(m_flTurn) - - float m_flBRWheelAxel; - float m_flBLWheelAxel; - float m_flFLWheelAxel; - float m_flFRWheelAxel; - - float m_flUseTime; - + + float m_flBRWheelAxel; + float m_flBLWheelAxel; + float m_flFLWheelAxel; + float m_flFRWheelAxel; + + float m_flUseTime; + public: - void prop_vehicle_driveable(void); + void prop_vehicle_driveable(void); virtual void Spawned(void); virtual void Physics(void); @@ -122,726 +124,747 @@ public: virtual void PlayerInput(void); virtual void OnRemoveEntity(void); -#ifdef CLIENT + nonvirtual void SpawnWheels(); + +#ifdef CLIENT virtual bool HideViewWeapon(void); virtual void PredictPreFrame(void); virtual void PredictPostFrame(void); virtual void ReceiveEntity(float,float); virtual void UpdateView(void); -#else +#else virtual void Respawn(void); virtual void OnPlayerUse(void); virtual void EvaluateEntity(void); virtual float SendEntity(entity,float); -#endif -}; +#endif +}; + +void +prop_vehicle_driveable::prop_vehicle_driveable(void) +{ + m_eDriver = __NULL__; + m_flBounceFactor = 1.25f; + m_flAcceleration = 600.0f; + m_flSkidSpeed = 256.0f; + m_flTraction = 5.0f; + m_flBreakFactor = 2.0f; + m_flSteerFactor = 1.0f; + m_flStraightenFactor = 1.0f; + m_vecGravityDir = [0,0,-1]; + m_iVehicleFlags |= VHF_FROZEN; + + m_eCollBox1 = __NULL__; + m_eCollBox2 = __NULL__; + + m_wlFL = __NULL__; + m_wlFR = __NULL__; + m_wlBL = __NULL__; + m_wlBR = __NULL__; +} + +#ifdef CLIENT +bool +prop_vehicle_driveable::HideViewWeapon(void) +{ + return true; +} +#endif + +void +prop_vehicle_driveable::Physics(void) +{ +#ifdef CLIENT + DriverRelink(); +#endif + + /* if nobody is in the car, we need to run physics here + * with fake input frames */ + if (GetDriver() == __NULL__) { +#ifdef SERVER + m_flTimeLength = frametime; + m_vecMoveValues = [0,0,0]; + m_iMoveButtons = 0; + RunVehiclePhysics(); +#else + setorigin(this, origin); +#endif + } else { + //crossprint(sprintf("Driver: %s\n", GetDriver().classname)); + } -void -prop_vehicle_driveable::prop_vehicle_driveable(void) -{ - m_eDriver = __NULL__; - m_flBounceFactor = 1.25f; - m_flAcceleration = 600.0f; - m_flSkidSpeed = 256.0f; - m_flTraction = 5.0f; - m_flBreakFactor = 2.0f; - m_flSteerFactor = 1.0f; - m_flStraightenFactor = 1.0f; - m_vecGravityDir = [0,0,-1]; - m_iVehicleFlags |= VHF_FROZEN; - hitcontentsmaski = CONTENTBIT_BODY | CONTENTBITS_POINTSOLID | CONTENTBIT_VEHICLECLIP; - - if (!m_eCollBox1) - m_eCollBox1 = spawn(NSEntity); - if (!m_eCollBox2) - m_eCollBox2 = spawn(NSEntity); - - { - m_eCollBox1.SetSize([-32,-32,0], [32,32,32]); - m_eCollBox2.SetSize([-32,-32,0], [32,32,32]); - } - - m_eCollBox1.hitcontentsmaski = hitcontentsmaski; - m_eCollBox2.hitcontentsmaski = hitcontentsmaski; - - if (!m_wlFL) - m_wlFL = spawn(prop_vehicle_driveable_wheel); - if (!m_wlFR) - m_wlFR = spawn(prop_vehicle_driveable_wheel); - if (!m_wlBL) - m_wlBL = spawn(prop_vehicle_driveable_wheel); - if (!m_wlBR) - m_wlBR = spawn(prop_vehicle_driveable_wheel); - - m_eCollBox1.owner = m_eCollBox2.owner = \ - m_wlFL.owner = m_wlFR.owner = \ - m_wlBL.owner = m_wlBR.owner = this; - - customphysics = Physics; -} - -#ifdef CLIENT -bool -prop_vehicle_driveable::HideViewWeapon(void) -{ - return true; -} -#endif - -void -prop_vehicle_driveable::Physics(void) -{ -#ifdef CLIENT - DriverRelink(); -#endif - - /* if nobody is in the car, we need to run physics here - * with fake input frames */ - if (GetDriver() == __NULL__) { -#ifdef SERVER - m_flTimeLength = frametime; - m_vecMoveValues = [0,0,0]; - m_iMoveButtons = 0; - RunVehiclePhysics(); -#else - setorigin(this, origin); -#endif - } else { - //crossprint(sprintf("Driver: %s\n", GetDriver().classname)); - } - HandleThink(); -} - -void -prop_vehicle_driveable::OnRemoveEntity(void) -{ - remove(m_wlFL); - remove(m_wlFR); - remove(m_wlBL); - remove(m_wlBR); - remove(m_eCollBox1); - remove(m_eCollBox2); -} - -#ifdef CLIENT -void -prop_vehicle_driveable::UpdateView(void) -{ - vector vecStart, vecEnd; - - pSeat->m_vecPredictedOrigin = origin; - makevectors(view_angles); - vecStart = [pSeat->m_vecPredictedOrigin[0], pSeat->m_vecPredictedOrigin[1], pSeat->m_vecPredictedOrigin[2] + 16] + (v_right * 4); - vecEnd = vecStart + (v_forward * -256) + [0,0,16] + (v_right * 4); - other = world; - traceline(vecStart, vecEnd, MOVE_OTHERONLY, this); - g_view.SetCameraOrigin(trace_endpos + (v_forward * 16)); - g_view.SetClientAngle(view_angles); -} - -void -prop_vehicle_driveable_wheel::PredictPreFrame(void) -{ - SAVE_STATE(angles) - SAVE_STATE(origin) - SAVE_STATE(velocity) -} - -void -prop_vehicle_driveable_wheel::PredictPostFrame(void) -{ - ROLL_BACK(angles) - ROLL_BACK(origin) - ROLL_BACK(velocity) -} -#endif - -void -prop_vehicle_driveable_wheel::Bounce(vector normal) -{ - prop_vehicle_driveable vehParent; - vehParent = (prop_vehicle_driveable)owner; - - vector vecBounce = (velocity * normal) * normal * vehParent.m_flBounceFactor; - velocity -= vecBounce; - vehParent.velocity = velocity; - -#ifdef SERVER - float flStregth = vlen((velocity * normal) * normal); - - if (flStregth > 96) { - Sound_Play(vehParent, CHAN_VOICE, "prop_vehicle_driveable.bounce"); - } -#endif -} - -void -prop_vehicle_driveable_wheel::Move(float flTimeLength) -{ - vector vecDest; - vector vecSavedNormal; - float flStepped; - float flMovetime; - int i; - - /* have a few attempts */ - for (i = 3, flMovetime = flTimeLength; flMovetime > 0 && i; i--) { - vecDest = origin + (velocity * flMovetime); - tracebox(origin, mins, maxs, vecDest, MOVE_NOMONSTERS, this); - - if (trace_startsolid) { - continue; - } - - origin = trace_endpos; - - if (trace_fraction < 1) { - vecSavedNormal = trace_plane_normal; - flMovetime -= flMovetime * trace_fraction; - - if (flMovetime) { - float roof_fraction; - vector roof_plane_normal; - - /* step up if we can */ - trace_endpos = origin; - trace_endpos[2] += 8; - - tracebox(origin, mins, maxs, trace_endpos, MOVE_NOMONSTERS, this); - flStepped = trace_endpos[2] - origin[2]; - - roof_fraction = trace_fraction; - roof_plane_normal = trace_plane_normal; - - vecDest = trace_endpos + velocity * flMovetime; - - /* only horizontally */ - vecDest[2] = trace_endpos[2]; - - /* move forwards */ - tracebox(trace_endpos, mins, maxs, vecDest, MOVE_NOMONSTERS, this); - - /* if we got anywhere, make this raised-step move count */ - if (trace_fraction != 0) { - float fwfrac; - vector fwplane; - - fwfrac = trace_fraction; - fwplane = trace_plane_normal; - - /* move down */ - vecDest = trace_endpos; - vecDest[2] -= flStepped + 1; - tracebox(trace_endpos, mins, maxs, vecDest, MOVE_NOMONSTERS, this); - - if (trace_fraction < 1 && trace_plane_normal[2] > 0.7f) { - flMovetime -= flMovetime * fwfrac; - - if (roof_fraction < 1) { - Bounce(roof_plane_normal); - } - - /* FIXME: do we need velocity < 0? */ - if (trace_fraction < 1) { - Bounce(trace_plane_normal); - } else if (fwfrac < 1) { - Bounce(fwplane); - } - - origin = trace_endpos; - continue; - } - } - } - - /* stepping failed, assume crash? */ - if (trace_ent == world) { - if (vlen(velocity) > 300) { - float impact; - impact = -dotproduct(trace_plane_normal, velocity); - int iImpactDamage = impact / 100; - } - } - - Bounce(vecSavedNormal); - /* Physics_DoTouch(this, trace_ent); */ - } else { - break; - } - } -} - -void -prop_vehicle_driveable_wheel::Accel(float flMoveTime, float m_flTurn) -{ - prop_vehicle_driveable vehParent; - entity eDriver; - float flTraction; - vector vecAngle; - - vehParent = (prop_vehicle_driveable)owner; - eDriver = vehParent.m_eDriver; - vecAngle = vehParent.angles; - - makevectors(vecAngle); - - if (m_flTurn) { - /* cripple turnrate by our current velocity */ - float turnbreak = bound(0, vlen(velocity), 100) * 0.5; - - /* rotates v_forward */ - rotatevectorsbyangle([ 0, m_flTurn * turnbreak, 0]); - } - - tracebox(origin, mins, maxs, origin - v_up, MOVE_NOMONSTERS, owner); - - /* allow a range, for 1qu's worth of spare tyre pressure. or something */ - flTraction = 1 - trace_fraction; - - /* air friction, doubles up for general rolling friction, ish */ - velocity *= 1 - flMoveTime * 0.1; - - if (flTraction) { - if (eDriver) { - velocity += v_forward * bound(-1, vehParent.m_vecMoveValues[0] / 400, 1) * vehParent.m_flAcceleration * flMoveTime * flTraction; - } - - /* test if this car is skidding */ - float skid = (velocity * v_right); - if ( fabs(skid) > vehParent.m_flSkidSpeed ) { - vehParent.vv_flags |= VEH_SKIDDING; - } - - /* nuke sideways velocity. if a wheel is off the ground this probably - means that it'll be pushed further. players should try not to roll - too much. */ - /* FIXME: push opposite wheel up slightly to model chassis momentum - not slowing as much as the wheel itself (zomg: race conditions!) */ - velocity -= (velocity * v_right) * v_right * vehParent.m_flTraction * flMoveTime * flTraction; - - if (!eDriver || (vehParent.m_iMoveButtons & INPUT_BUTTON2 || vehParent.m_vecMoveValues[2] > 0)) { - vector t; - - /* empty cars are assumed to have their brakes on. - nuke forward velocity. if a wheel is off the ground this probably - means that it'll be pushed further. players should try not to - roll too much. - - Note: really we ought to be applying some axel friction even - when not breaking, but we'll just depend on air friction for - that. */ - velocity -= (velocity * v_forward) * v_forward * vehParent.m_flBreakFactor * flMoveTime * flTraction; - - /* if break is on, nuke the final part of the velocity, so we can - become truely motionless.*/ - t = velocity - velocity * dotproduct(velocity, vehParent.m_vecGravityDir); - if (vlen(t) < 15) { - velocity -= t; - } - - /* don't bother with gravity if we're already on the ground and - breaking. this avoids weird slides. */ - if (!trace_fraction && trace_plane_normal * vehParent.m_vecGravityDir < -0.7f) { - return; - } - } - } - - /* apply gravity */ - velocity += vehParent.m_vecGravityDir * flMoveTime * serverkeyfloat("phy_gravity") * trace_fraction; - - tracebox(origin, mins * 4.0, maxs * 4.0, origin, MOVE_NORMAL, owner); - if (trace_ent && trace_ent != vehParent.m_eDriver) { - int iImpactDamage = vlen(velocity) / 10; - - if (iImpactDamage > 10) { - trace_ent.velocity = velocity * 2.0 + [0,0,500]; - velocity *= 0.25f; -#ifdef SERVER - if (trace_ent.takedamage) { - NSSurfacePropEntity foo = (NSSurfacePropEntity)trace_ent; +} + +void +prop_vehicle_driveable::OnRemoveEntity(void) +{ + if (m_wlFL) + m_wlFL.Destroy(); + if (m_wlFR) + m_wlFR.Destroy(); + if (m_wlBL) + m_wlBL.Destroy(); + if (m_wlBR) + m_wlBR.Destroy(); + if (m_eCollBox1) + m_eCollBox1.Destroy(); + if (m_eCollBox2) + m_eCollBox2.Destroy(); +} + +#ifdef CLIENT +void +prop_vehicle_driveable::UpdateView(void) +{ + vector vecStart, vecEnd; + + pSeat->m_vecPredictedOrigin = origin; + makevectors(view_angles); + vecStart = [pSeat->m_vecPredictedOrigin[0], pSeat->m_vecPredictedOrigin[1], pSeat->m_vecPredictedOrigin[2] + 16] + (v_right * 4); + vecEnd = vecStart + (v_forward * -256) + [0,0,16] + (v_right * 4); + other = world; + traceline(vecStart, vecEnd, MOVE_OTHERONLY, this); + g_view.SetCameraOrigin(trace_endpos + (v_forward * 16)); + g_view.SetClientAngle(view_angles); +} + +void +prop_vehicle_driveable_wheel::PredictPreFrame(void) +{ + SAVE_STATE(angles) + SAVE_STATE(origin) + SAVE_STATE(velocity) +} + +void +prop_vehicle_driveable_wheel::PredictPostFrame(void) +{ + ROLL_BACK(angles) + ROLL_BACK(origin) + ROLL_BACK(velocity) +} +#endif + +void +prop_vehicle_driveable_wheel::Bounce(vector normal) +{ + prop_vehicle_driveable vehParent; + vehParent = (prop_vehicle_driveable)owner; + + vector vecBounce = (velocity * normal) * normal * vehParent.m_flBounceFactor; + velocity -= vecBounce; + vehParent.velocity = velocity; + +#ifdef SERVER + float flStregth = vlen((velocity * normal) * normal); + + if (flStregth > 96) { + Sound_Play(vehParent, CHAN_VOICE, "prop_vehicle_driveable.bounce"); + } +#endif +} + +void +prop_vehicle_driveable_wheel::Move(float flTimeLength) +{ + vector vecDest; + vector vecSavedNormal; + float flStepped; + float flMovetime; + int i; + + /* have a few attempts */ + for (i = 3, flMovetime = flTimeLength; flMovetime > 0 && i; i--) { + vecDest = origin + (velocity * flMovetime); + tracebox(origin, mins, maxs, vecDest, MOVE_NOMONSTERS, this); + + if (trace_startsolid) { + continue; + } + + origin = trace_endpos; + + if (trace_fraction < 1) { + vecSavedNormal = trace_plane_normal; + flMovetime -= flMovetime * trace_fraction; + + if (flMovetime) { + float roof_fraction; + vector roof_plane_normal; + + /* step up if we can */ + trace_endpos = origin; + trace_endpos[2] += 8; + + tracebox(origin, mins, maxs, trace_endpos, MOVE_NOMONSTERS, this); + flStepped = trace_endpos[2] - origin[2]; + + roof_fraction = trace_fraction; + roof_plane_normal = trace_plane_normal; + + vecDest = trace_endpos + velocity * flMovetime; + + /* only horizontally */ + vecDest[2] = trace_endpos[2]; + + /* move forwards */ + tracebox(trace_endpos, mins, maxs, vecDest, MOVE_NOMONSTERS, this); + + /* if we got anywhere, make this raised-step move count */ + if (trace_fraction != 0) { + float fwfrac; + vector fwplane; + + fwfrac = trace_fraction; + fwplane = trace_plane_normal; + + /* move down */ + vecDest = trace_endpos; + vecDest[2] -= flStepped + 1; + tracebox(trace_endpos, mins, maxs, vecDest, MOVE_NOMONSTERS, this); + + if (trace_fraction < 1 && trace_plane_normal[2] > 0.7f) { + flMovetime -= flMovetime * fwfrac; + + if (roof_fraction < 1) { + Bounce(roof_plane_normal); + } + + /* FIXME: do we need velocity < 0? */ + if (trace_fraction < 1) { + Bounce(trace_plane_normal); + } else if (fwfrac < 1) { + Bounce(fwplane); + } + + origin = trace_endpos; + continue; + } + } + } + + /* stepping failed, assume crash? */ + if (trace_ent == world) { + if (vlen(velocity) > 300) { + float impact; + impact = -dotproduct(trace_plane_normal, velocity); + int iImpactDamage = impact / 100; + } + } + + Bounce(vecSavedNormal); + /* Physics_DoTouch(this, trace_ent); */ + } else { + break; + } + } +} + +void +prop_vehicle_driveable_wheel::Accel(float flMoveTime, float m_flTurn) +{ + prop_vehicle_driveable vehParent; + entity eDriver; + float flTraction; + vector vecAngle; + + vehParent = (prop_vehicle_driveable)owner; + eDriver = vehParent.m_eDriver; + vecAngle = vehParent.angles; + + makevectors(vecAngle); + + if (m_flTurn) { + /* cripple turnrate by our current velocity */ + float turnbreak = bound(0, vlen(velocity), 100) * 0.5; + + /* rotates v_forward */ + rotatevectorsbyangle([ 0, m_flTurn * turnbreak, 0]); + } + + tracebox(origin, mins, maxs, origin - v_up, MOVE_NOMONSTERS, owner); + + /* allow a range, for 1qu's worth of spare tyre pressure. or something */ + flTraction = 1 - trace_fraction; + + /* air friction, doubles up for general rolling friction, ish */ + velocity *= 1 - flMoveTime * 0.1; + + if (flTraction) { + if (eDriver) { + velocity += v_forward * bound(-1, vehParent.m_vecMoveValues[0] / 400, 1) * vehParent.m_flAcceleration * flMoveTime * flTraction; + } + + /* test if this car is skidding */ + float skid = (velocity * v_right); + if ( fabs(skid) > vehParent.m_flSkidSpeed ) { + vehParent.vv_flags |= VEH_SKIDDING; + } + + /* nuke sideways velocity. if a wheel is off the ground this probably + means that it'll be pushed further. players should try not to roll + too much. */ + /* FIXME: push opposite wheel up slightly to model chassis momentum + not slowing as much as the wheel itself (zomg: race conditions!) */ + velocity -= (velocity * v_right) * v_right * vehParent.m_flTraction * flMoveTime * flTraction; + + if (!eDriver || (vehParent.m_iMoveButtons & INPUT_BUTTON2 || vehParent.m_vecMoveValues[2] > 0)) { + vector t; + + /* empty cars are assumed to have their brakes on. + nuke forward velocity. if a wheel is off the ground this probably + means that it'll be pushed further. players should try not to + roll too much. + + Note: really we ought to be applying some axel friction even + when not breaking, but we'll just depend on air friction for + that. */ + velocity -= (velocity * v_forward) * v_forward * vehParent.m_flBreakFactor * flMoveTime * flTraction; + + /* if break is on, nuke the final part of the velocity, so we can + become truely motionless.*/ + t = velocity - velocity * dotproduct(velocity, vehParent.m_vecGravityDir); + if (vlen(t) < 15) { + velocity -= t; + } + + /* don't bother with gravity if we're already on the ground and + breaking. this avoids weird slides. */ + if (!trace_fraction && trace_plane_normal * vehParent.m_vecGravityDir < -0.7f) { + return; + } + } + } + + /* apply gravity */ + velocity += vehParent.m_vecGravityDir * flMoveTime * serverkeyfloat("phy_gravity") * trace_fraction; + + tracebox(origin, mins * 4.0, maxs * 4.0, origin, MOVE_NORMAL, owner); + if (trace_ent && trace_ent != vehParent.m_eDriver) { + int iImpactDamage = vlen(velocity) / 10; + + if (iImpactDamage > 10) { + trace_ent.velocity = velocity * 2.0 + [0,0,500]; + velocity *= 0.25f; +#ifdef SERVER + if (trace_ent.takedamage) { + NSSurfacePropEntity foo = (NSSurfacePropEntity)trace_ent; vector dmgDir = dirFromTarget(trace_endpos, foo.origin); NSDict damageDecl = spawn(NSDict); damageDecl.AddKey("damage", itos(iImpactDamage)); - entityDamage(foo, this, vehParent.m_eDriver, damageDecl.GetDeclBody(), "", trace_endpos, dmgDir, foo.origin); + combat.Damage(foo, this, vehParent.m_eDriver, damageDecl.GetDeclBody(), trace_endpos, dmgDir, foo.origin); remove(damageDecl); - //print(sprintf("Delivering %i impact damage\n", iImpactDamage)); - } -#endif - } - } -} - -void -prop_vehicle_driveable_wheel::UpdateSuspension(float flTimeLength) -{ - float flDamp; - float flForce; - - if (fabs(m_flSuspension) > 0.001 || fabs(m_flSuspensionForce) > 0.001) { - m_flSuspension += m_flSuspensionForce * flTimeLength; - - flForce = bound(0, flTimeLength * 65, 2); - flDamp = 1 - (flTimeLength * 4); - if (flDamp < 0) { - flDamp = 0; - } - m_flSuspensionForce *= flDamp; - m_flSuspensionForce -= m_flSuspension * flForce; - m_flSuspension = bound(-15, m_flSuspension, 15); - } -} - -void -prop_vehicle_driveable_wheel::Physics(float turnrate, float flTimeLength) -{ - vector owner_pos; - - /* try to correct the wheel's position, in case it got stuck */ - owner_pos = owner.origin + (owner.mins + owner.maxs) * 0.5f; - tracebox(owner_pos, mins, maxs, origin, MOVE_NORMAL, owner); - setorigin(this, trace_endpos); - - /* see if we're in-air */ - other = world; - tracebox(origin, mins, maxs, origin - [0,0,1], MOVE_OTHERONLY, this); - if (!trace_startsolid) { - if ((trace_fraction < 1) && (trace_plane_normal[2] > 0.7)) { - flags |= FL_ONGROUND; - } else { - flags &= ~FL_ONGROUND; - m_flSuspensionForce += flTimeLength * 200.0; - } - } - - Accel(flTimeLength / 2, turnrate); - Move(flTimeLength); - Accel(flTimeLength / 2, turnrate); - UpdateSuspension(flTimeLength); - //print(sprintf("suspension: %d, force: %d\n", m_flSuspension, m_flSuspensionForce)); -} - -void -prop_vehicle_driveable_wheel::prop_vehicle_driveable_wheel(void) -{ - mins = [-8,-8,-35]; - maxs = [8,8,8]; - hitcontentsmaski = CONTENTBIT_BODY | CONTENTBITS_POINTSOLID | CONTENTBIT_VEHICLECLIP; -} - -#ifdef CLIENT -void -prop_vehicle_driveable::PredictPreFrame(void) -{ - SAVE_STATE(modelindex) - SAVE_STATE(origin) - SAVE_STATE(angles) - SAVE_STATE(velocity) - SAVE_STATE(m_flTurn) - SAVE_STATE(flags) - SAVE_STATE(driver_entnum) - - m_wlFL.PredictPreFrame(); - m_wlFR.PredictPreFrame(); - m_wlBL.PredictPreFrame(); - m_wlBR.PredictPreFrame(); -} - -void -prop_vehicle_driveable::PredictPostFrame(void) -{ - ROLL_BACK(modelindex) - ROLL_BACK(angles) - ROLL_BACK(origin) - ROLL_BACK(velocity) - ROLL_BACK(m_flTurn) - ROLL_BACK(flags) - ROLL_BACK(driver_entnum) - - m_wlFL.PredictPostFrame(); - m_wlFR.PredictPostFrame(); - m_wlBL.PredictPostFrame(); - m_wlBR.PredictPostFrame(); -} -#endif - -void -prop_vehicle_driveable::WeaponInput(void) -{ - -} - -void -prop_vehicle_driveable::PlayerInput(void) -{ - m_vecMoveValues = input_movevalues; - m_iMoveButtons = input_buttons; - m_flTimeLength = input_timelength; - - /* prediction frame... */ - RunVehiclePhysics(); - -#ifdef SERVER - /* allow us to exit */ - if (m_flUseTime < time) { - if (input_buttons & INPUT_BUTTON5) { - eActivator = m_eDriver; - OnPlayerUse(); - input_buttons &= ~INPUT_BUTTON5; - } - } -#endif - - WeaponInput(); - - /* only allow use key */ - input_buttons = (input_buttons & INPUT_BUTTON5); -} - -void -prop_vehicle_driveable::RunVehiclePhysics(void) -{ -#if SERVER - /* eject the dead */ - if (m_eDriver && m_eDriver.health <= 0) { - PlayerLeave((NSClientPlayer)m_eDriver); - } -#endif - - if (m_eDriver) { - float y; - - y = m_vecMoveValues[1]; - y = bound(-200, y, 200) / 200; - y *= m_flSteerFactor; - - if (y) { - if (y < 0 && m_flTurn < 0) { - m_flTurn = 0.0f; - } else if (y > 0 && m_flTurn > 0) { - m_flTurn = 0.0f; - } else { - m_flTurn = bound(-1, m_flTurn - y * m_flTimeLength, 1); - } - } else { - /* straighten wheels forward over time */ - if (m_flTurn < 0) { - m_flTurn = min(0, m_flTurn + m_flTimeLength * m_flStraightenFactor); - } else if (m_flTurn > 0) { - m_flTurn = max(0, m_flTurn - m_flTimeLength * m_flStraightenFactor); - } - } - - PlayerUpdateFlags(); - } - - if (spawnflags & VEHSF_NOFLIP) { - angles[0] = bound (-45, angles[0], 45); - angles[2] = bound (-45, angles[2], 45); - } - - vv_flags &= ~VEH_SKIDDING; - - angles = fixAngle(angles); - - velocity[0] = bound(-1000, velocity[0], 1000); - velocity[1] = bound(-1000, velocity[1], 1000); - velocity[2] = bound(-1000, velocity[2], 1000); - - makevectors(angles); - - setorigin( m_wlFL, origin ); - setorigin( m_wlBL, m_wlFL.origin - v_forward * 85 ); - setorigin( m_wlFL, m_wlFL.origin + v_forward * 85 ); - setorigin( m_wlFR, m_wlFL.origin + v_right * 40 ); - setorigin( m_wlFL, m_wlFL.origin - v_right * 40 ); - setorigin( m_wlBR, m_wlBL.origin + v_right * 40 ); - setorigin( m_wlBL, m_wlBL.origin - v_right * 40 ); - - m_wlFL.Physics( this.m_flTurn, m_flTimeLength); - m_wlFR.Physics( this.m_flTurn, m_flTimeLength); - m_wlBL.Physics( 0, m_flTimeLength); - m_wlBR.Physics( 0, m_flTimeLength); - - velocity = m_wlFL.velocity; - velocity += m_wlFR.velocity; - velocity += m_wlBL.velocity; - velocity += m_wlBR.velocity; - velocity *= 0.25f; - - v_right = (m_wlFR.origin - m_wlFL.origin); - v_right += (m_wlBR.origin - m_wlBL.origin); - v_forward = (m_wlFL.origin + m_wlFR.origin); - v_forward -= (m_wlBL.origin + m_wlBR.origin); - v_up = -crossproduct(v_forward, v_right); - angles = vectoangles( v_forward, v_up ); - - /* figure out the new chassis position */ - vector new_origin; - new_origin = m_wlFL.origin; - new_origin += m_wlFR.origin; - new_origin += m_wlBL.origin; - new_origin += m_wlBR.origin; - new_origin *= 0.25f; - setorigin(this, new_origin); - - makevectors(angles); - m_eCollBox1.SetOrigin(origin + (v_forward * 64)); - m_eCollBox2.SetOrigin(origin + (v_forward * -72)); - m_eCollBox1.SetSolid(SOLID_BBOX); - m_eCollBox2.SetSolid(SOLID_BBOX); - - PlayerAlign(); - - /* actiony stuff */ -} - -#ifdef SERVER -void -prop_vehicle_driveable::OnPlayerUse(void) -{ - if (m_flUseTime > time) - return; - - if (m_eDriver == eActivator) { - PlayerLeave((NSClientPlayer)eActivator); - setorigin(eActivator, GetExitPos()); - } else if (!m_eDriver) { - PlayerEnter((NSClientPlayer)eActivator); - m_vecPlayerPos = [0,0,0]; - } - m_flUseTime = time + 2.0f; -} - -void -prop_vehicle_driveable::Respawn(void) -{ - SetMovetype(MOVETYPE_NONE); - SetSolid(SOLID_BBOX); - SetOrigin(GetSpawnVector("origin") + [0,0,32]); - SetAngles(GetSpawnVector("angles")); - SetModel(GetSpawnString("model")); - - m_flBRWheelAxel = gettagindex( this, "RRWheelAxel" ); - m_flBLWheelAxel = gettagindex( this, "RLWheelAxel" ); - m_flFLWheelAxel = gettagindex( this, "FLWheelAxel" ); - m_flFRWheelAxel = gettagindex( this, "FRWheelAxel" ); - - m_wlFL.velocity = - m_wlFR.velocity = - m_wlBL.velocity = - m_wlBR.velocity = - velocity = [0,0,0]; - PlayerUse = OnPlayerUse; - setsize( this, [-50,-50,0], [50,50,64]); - - if (m_eDriver) - PlayerLeave((NSClientPlayer)m_eDriver); - - SendFlags = -1; -} -#endif - -#ifdef CLIENT -void -prop_vehicle_driveable::ReceiveEntity(float flNew, float flSendFlags) -{ - if (flSendFlags & VEHFL_DRIVER) { - driver_entnum = readentitynum(); - DriverRelink(); - } - - if (flSendFlags & VEHFL_MODELINDEX) { - modelindex = readshort(); - m_vecSeatOffest[0] = readfloat(); - m_vecSeatOffest[1] = readfloat(); - m_vecSeatOffest[2] = readfloat(); - setsize( this, [-50,-50,0], [50,50,64]); - } - - if (flSendFlags & VEHFL_ORIGIN) { - origin[0] = readcoord(); - origin[1] = readcoord(); - origin[2] = readcoord(); - setorigin(this, origin); - - makevectors(angles); - - setorigin( m_wlFL, origin ); - setorigin( m_wlBL, m_wlFL.origin - v_forward * 85 ); - setorigin( m_wlFL, m_wlFL.origin + v_forward * 85 ); - setorigin( m_wlFR, m_wlFL.origin + v_right * 40 ); - setorigin( m_wlFL, m_wlFL.origin - v_right * 40 ); - setorigin( m_wlBR, m_wlBL.origin + v_right * 40 ); - setorigin( m_wlBL, m_wlBL.origin - v_right * 40 ); - m_eCollBox1.SetOrigin(origin + (v_forward * 64)); - m_eCollBox2.SetOrigin(origin + (v_forward * -72)); - } - - if (flSendFlags & VEHFL_ANGLES) { - angles[0] = readfloat(); - angles[1] = readfloat(); - angles[2] = readfloat(); - } - - if (flSendFlags & VEHFL_VELOCITY) { - velocity[0] = readfloat(); - velocity[1] = readfloat(); - velocity[2] = readfloat(); - } - - if (flSendFlags & VEHFL_TURNING) - m_flTurn = readfloat(); - - if (flSendFlags & VEHFL_FLAGS) - flags = readfloat(); - - if (flNew) { - drawmask = MASK_ENGINE; - SetMovetype(MOVETYPE_NONE); - SetSolid(SOLID_BBOX); - - m_flBRWheelAxel = gettagindex( this, "RRWheelAxel" ); - m_flBLWheelAxel = gettagindex( this, "RLWheelAxel" ); - m_flFLWheelAxel = gettagindex( this, "FLWheelAxel" ); - m_flFRWheelAxel = gettagindex( this, "FRWheelAxel" ); - - m_wlFL.velocity = - m_wlFR.velocity = - m_wlBL.velocity = - m_wlBR.velocity = - velocity = [0,0,0]; - RunVehiclePhysics(); - customphysics = Physics; - } - - PredictPreFrame(); -} -#else -void -prop_vehicle_driveable::EvaluateEntity(void) -{ - /* while the engine is still handling physics for these, we can't - * predict when origin/angle might change */ - if (ATTR_CHANGED(origin)) - SetSendFlags(VEHFL_ORIGIN); - - if (ATTR_CHANGED(angles)) { - angles = fixAngle(angles); - SetSendFlags(VEHFL_ANGLES); - } - if (ATTR_CHANGED(modelindex)) - SetSendFlags(VEHFL_MODELINDEX); - if (ATTR_CHANGED(velocity)) - SetSendFlags(VEHFL_VELOCITY); - if (ATTR_CHANGED(m_flTurn)) - SetSendFlags(VEHFL_TURNING); - if (ATTR_CHANGED(m_eDriver)) - SetSendFlags(VEHFL_DRIVER); - if (ATTR_CHANGED(flags)) - SetSendFlags(VEHFL_FLAGS); - + //print(sprintf("Delivering %i impact damage\n", iImpactDamage)); + } +#endif + } + } +} + +void +prop_vehicle_driveable_wheel::UpdateSuspension(float flTimeLength) +{ + float flDamp; + float flForce; + + if (fabs(m_flSuspension) > 0.001 || fabs(m_flSuspensionForce) > 0.001) { + m_flSuspension += m_flSuspensionForce * flTimeLength; + + flForce = bound(0, flTimeLength * 65, 2); + flDamp = 1 - (flTimeLength * 4); + if (flDamp < 0) { + flDamp = 0; + } + m_flSuspensionForce *= flDamp; + m_flSuspensionForce -= m_flSuspension * flForce; + m_flSuspension = bound(-15, m_flSuspension, 15); + } +} + +void +prop_vehicle_driveable_wheel::Physics(float turnrate, float flTimeLength) +{ + vector owner_pos; + + /* try to correct the wheel's position, in case it got stuck */ + owner_pos = owner.origin + (owner.mins + owner.maxs) * 0.5f; + tracebox(owner_pos, mins, maxs, origin, MOVE_NORMAL, owner); + setorigin(this, trace_endpos); + + /* see if we're in-air */ + other = world; + tracebox(origin, mins, maxs, origin - [0,0,1], MOVE_OTHERONLY, this); + if (!trace_startsolid) { + if ((trace_fraction < 1) && (trace_plane_normal[2] > 0.7)) { + flags |= FL_ONGROUND; + } else { + flags &= ~FL_ONGROUND; + m_flSuspensionForce += flTimeLength * 200.0; + } + } + + Accel(flTimeLength / 2, turnrate); + Move(flTimeLength); + Accel(flTimeLength / 2, turnrate); + UpdateSuspension(flTimeLength); + //print(sprintf("suspension: %d, force: %d\n", m_flSuspension, m_flSuspensionForce)); +} + +void +prop_vehicle_driveable_wheel::prop_vehicle_driveable_wheel(void) +{ + mins = [-8,-8,-35]; + maxs = [8,8,8]; + hitcontentsmaski = CONTENTBIT_BODY | CONTENTBITS_POINTSOLID | CONTENTBIT_VEHICLECLIP; +} + +#ifdef CLIENT +void +prop_vehicle_driveable::PredictPreFrame(void) +{ + SAVE_STATE(modelindex) + SAVE_STATE(origin) + SAVE_STATE(angles) + SAVE_STATE(velocity) + SAVE_STATE(m_flTurn) + SAVE_STATE(flags) + SAVE_STATE(driver_entnum) + + m_wlFL.PredictPreFrame(); + m_wlFR.PredictPreFrame(); + m_wlBL.PredictPreFrame(); + m_wlBR.PredictPreFrame(); +} + +void +prop_vehicle_driveable::PredictPostFrame(void) +{ + ROLL_BACK(modelindex) + ROLL_BACK(angles) + ROLL_BACK(origin) + ROLL_BACK(velocity) + ROLL_BACK(m_flTurn) + ROLL_BACK(flags) + ROLL_BACK(driver_entnum) + + m_wlFL.PredictPostFrame(); + m_wlFR.PredictPostFrame(); + m_wlBL.PredictPostFrame(); + m_wlBR.PredictPostFrame(); +} +#endif + +void +prop_vehicle_driveable::WeaponInput(void) +{ + +} + +void +prop_vehicle_driveable::PlayerInput(void) +{ + m_vecMoveValues = input_movevalues; + m_iMoveButtons = input_buttons; + m_flTimeLength = input_timelength; + + /* prediction frame... */ + RunVehiclePhysics(); + +#ifdef SERVER + /* allow us to exit */ + if (m_flUseTime < time) { + if (input_buttons & INPUT_BUTTON5) { + eActivator = m_eDriver; + OnPlayerUse(); + input_buttons &= ~INPUT_BUTTON5; + } + } +#endif + + WeaponInput(); + + /* only allow use key */ + input_buttons = (input_buttons & INPUT_BUTTON5); +} + +void +prop_vehicle_driveable::RunVehiclePhysics(void) +{ +#if SERVER + /* eject the dead */ + if (m_eDriver && m_eDriver.health <= 0) { + PlayerLeave((NSClientPlayer)m_eDriver); + } +#endif + + if (m_eDriver) { + float y; + + y = m_vecMoveValues[1]; + y = bound(-200, y, 200) / 200; + y *= m_flSteerFactor; + + if (y) { + if (y < 0 && m_flTurn < 0) { + m_flTurn = 0.0f; + } else if (y > 0 && m_flTurn > 0) { + m_flTurn = 0.0f; + } else { + m_flTurn = bound(-1, m_flTurn - y * m_flTimeLength, 1); + } + } else { + /* straighten wheels forward over time */ + if (m_flTurn < 0) { + m_flTurn = min(0, m_flTurn + m_flTimeLength * m_flStraightenFactor); + } else if (m_flTurn > 0) { + m_flTurn = max(0, m_flTurn - m_flTimeLength * m_flStraightenFactor); + } + } + + PlayerUpdateFlags(); + } + + if (spawnflags & VEHSF_NOFLIP) { + angles[0] = bound (-45, angles[0], 45); + angles[2] = bound (-45, angles[2], 45); + } + + vv_flags &= ~VEH_SKIDDING; + + angles = fixAngle(angles); + + velocity[0] = bound(-1000, velocity[0], 1000); + velocity[1] = bound(-1000, velocity[1], 1000); + velocity[2] = bound(-1000, velocity[2], 1000); + + makevectors(angles); + + setorigin( m_wlFL, origin ); + setorigin( m_wlBL, m_wlFL.origin - v_forward * 85 ); + setorigin( m_wlFL, m_wlFL.origin + v_forward * 85 ); + setorigin( m_wlFR, m_wlFL.origin + v_right * 40 ); + setorigin( m_wlFL, m_wlFL.origin - v_right * 40 ); + setorigin( m_wlBR, m_wlBL.origin + v_right * 40 ); + setorigin( m_wlBL, m_wlBL.origin - v_right * 40 ); + + m_wlFL.Physics( this.m_flTurn, m_flTimeLength); + m_wlFR.Physics( this.m_flTurn, m_flTimeLength); + m_wlBL.Physics( 0, m_flTimeLength); + m_wlBR.Physics( 0, m_flTimeLength); + + velocity = m_wlFL.velocity; + velocity += m_wlFR.velocity; + velocity += m_wlBL.velocity; + velocity += m_wlBR.velocity; + velocity *= 0.25f; + + v_right = (m_wlFR.origin - m_wlFL.origin); + v_right += (m_wlBR.origin - m_wlBL.origin); + v_forward = (m_wlFL.origin + m_wlFR.origin); + v_forward -= (m_wlBL.origin + m_wlBR.origin); + v_up = -crossproduct(v_forward, v_right); + angles = vectoangles( v_forward, v_up ); + + /* figure out the new chassis position */ + vector new_origin; + new_origin = m_wlFL.origin; + new_origin += m_wlFR.origin; + new_origin += m_wlBL.origin; + new_origin += m_wlBR.origin; + new_origin *= 0.25f; + setorigin(this, new_origin); + + makevectors(angles); + m_eCollBox1.SetOrigin(origin + (v_forward * 64)); + m_eCollBox2.SetOrigin(origin + (v_forward * -72)); + m_eCollBox1.SetSolid(SOLID_BBOX); + m_eCollBox2.SetSolid(SOLID_BBOX); + + PlayerAlign(); + + /* actiony stuff */ +} + +#ifdef SERVER +void +prop_vehicle_driveable::OnPlayerUse(void) +{ + if (m_flUseTime > time) + return; + + if (m_eDriver == eActivator) { + PlayerLeave((NSClientPlayer)eActivator); + setorigin(eActivator, GetExitPos()); + } else if (!m_eDriver) { + PlayerEnter((NSClientPlayer)eActivator); + m_vecPlayerPos = [0,0,0]; + } + m_flUseTime = time + 2.0f; +} + +void +prop_vehicle_driveable::Respawn(void) +{ + SetMovetype(MOVETYPE_NONE); + SetSolid(SOLID_BBOX); + SetOrigin(GetSpawnVector("origin") + [0,0,32]); + SetAngles(GetSpawnVector("angles")); + SetModel(GetSpawnString("model")); + + m_flBRWheelAxel = gettagindex( this, "Rig_Buggy_Axel_RR" ); + m_flBLWheelAxel = gettagindex( this, "Rig_Buggy_Axel_RL" ); + m_flFLWheelAxel = gettagindex( this, "Rig_Buggy_Axel_FL" ); + m_flFRWheelAxel = gettagindex( this, "Rig_Buggy_Axel_FR" ); + + m_wlFL.velocity = + m_wlFR.velocity = + m_wlBL.velocity = + m_wlBR.velocity = + velocity = [0,0,0]; + PlayerUse = OnPlayerUse; + setsize( this, [-50,-50,0], [50,50,64]); + + if (m_eDriver) + PlayerLeave((NSClientPlayer)m_eDriver); + + SendFlags = -1; +} +#endif + +void +prop_vehicle_driveable::SpawnWheels(void) +{ + if (!m_eCollBox1) + m_eCollBox1 = spawn(NSEntity); + if (!m_eCollBox2) + m_eCollBox2 = spawn(NSEntity); + + { + m_eCollBox1.SetSize([-32,-32,0], [32,32,32]); + m_eCollBox2.SetSize([-32,-32,0], [32,32,32]); + } + + m_eCollBox1.hitcontentsmaski = hitcontentsmaski; + m_eCollBox2.hitcontentsmaski = hitcontentsmaski; + + if (!m_wlFL) + m_wlFL = spawn(prop_vehicle_driveable_wheel); + if (!m_wlFR) + m_wlFR = spawn(prop_vehicle_driveable_wheel); + if (!m_wlBL) + m_wlBL = spawn(prop_vehicle_driveable_wheel); + if (!m_wlBR) + m_wlBR = spawn(prop_vehicle_driveable_wheel); + + m_eCollBox1.owner = m_eCollBox2.owner = \ + m_wlFL.owner = m_wlFR.owner = \ + m_wlBL.owner = m_wlBR.owner = this; +} + +#ifdef CLIENT +void +prop_vehicle_driveable::ReceiveEntity(float flNew, float flSendFlags) +{ + if (flSendFlags & VEHFL_DRIVER) { + driver_entnum = readentitynum(); + DriverRelink(); + } + + if (flSendFlags & VEHFL_MODELINDEX) { + modelindex = readshort(); + m_vecSeatOffest[0] = readfloat(); + m_vecSeatOffest[1] = readfloat(); + m_vecSeatOffest[2] = readfloat(); + setsize( this, [-50,-50,0], [50,50,64]); + } + + if (flNew) { + SpawnWheels(); + } + + if (flSendFlags & VEHFL_ORIGIN) { + origin[0] = readcoord(); + origin[1] = readcoord(); + origin[2] = readcoord(); + setorigin(this, origin); + + makevectors(angles); + + setorigin( m_wlFL, origin ); + setorigin( m_wlBL, m_wlFL.origin - v_forward * 85 ); + setorigin( m_wlFL, m_wlFL.origin + v_forward * 85 ); + setorigin( m_wlFR, m_wlFL.origin + v_right * 40 ); + setorigin( m_wlFL, m_wlFL.origin - v_right * 40 ); + setorigin( m_wlBR, m_wlBL.origin + v_right * 40 ); + setorigin( m_wlBL, m_wlBL.origin - v_right * 40 ); + m_eCollBox1.SetOrigin(origin + (v_forward * 64)); + m_eCollBox2.SetOrigin(origin + (v_forward * -72)); + } + + if (flSendFlags & VEHFL_ANGLES) { + angles[0] = readfloat(); + angles[1] = readfloat(); + angles[2] = readfloat(); + } + + if (flSendFlags & VEHFL_VELOCITY) { + velocity[0] = readfloat(); + velocity[1] = readfloat(); + velocity[2] = readfloat(); + } + + if (flSendFlags & VEHFL_TURNING) + m_flTurn = readfloat(); + + if (flSendFlags & VEHFL_FLAGS) + flags = readfloat(); + + if (flNew) { + drawmask = MASK_ENGINE; + SetMovetype(MOVETYPE_NONE); + SetSolid(SOLID_BBOX); + + m_flBRWheelAxel = gettagindex( this, "Rig_Buggy_Axel_RR" ); + m_flBLWheelAxel = gettagindex( this, "Rig_Buggy_Axel_RL" ); + m_flFLWheelAxel = gettagindex( this, "Rig_Buggy_Axel_FL" ); + m_flFRWheelAxel = gettagindex( this, "Rig_Buggy_Axel_FR" ); + + m_wlFL.velocity = + m_wlFR.velocity = + m_wlBL.velocity = + m_wlBR.velocity = + velocity = [0,0,0]; + RunVehiclePhysics(); + customphysics = Physics; + } + + PredictPreFrame(); +} +#else +void +prop_vehicle_driveable::EvaluateEntity(void) +{ + /* while the engine is still handling physics for these, we can't + * predict when origin/angle might change */ + if (ATTR_CHANGED(origin)) + SetSendFlags(VEHFL_ORIGIN); + + if (ATTR_CHANGED(angles)) { + angles = fixAngle(angles); + SetSendFlags(VEHFL_ANGLES); + } + if (ATTR_CHANGED(modelindex)) + SetSendFlags(VEHFL_MODELINDEX); + if (ATTR_CHANGED(velocity)) + SetSendFlags(VEHFL_VELOCITY); + if (ATTR_CHANGED(m_flTurn)) + SetSendFlags(VEHFL_TURNING); + if (ATTR_CHANGED(m_eDriver)) + SetSendFlags(VEHFL_DRIVER); + if (ATTR_CHANGED(flags)) + SetSendFlags(VEHFL_FLAGS); + SAVE_STATE(origin) SAVE_STATE(angles) SAVE_STATE(modelindex); @@ -849,62 +872,69 @@ prop_vehicle_driveable::EvaluateEntity(void) SAVE_STATE(m_flTurn) SAVE_STATE(m_eDriver) SAVE_STATE(flags) -} - -float -prop_vehicle_driveable::SendEntity(entity ePVSent, float flSendFlags) -{ - WriteByte(MSG_ENTITY, ENT_VEH_4WHEEL); - WriteFloat(MSG_ENTITY, flSendFlags); - - if (!modelindex) - return (false); - - if (flSendFlags & VEHFL_DRIVER) { - WriteEntity(MSG_ENTITY, m_eDriver); - } - - if (flSendFlags & VEHFL_MODELINDEX) { - WriteShort(MSG_ENTITY, modelindex); - WriteFloat(MSG_ENTITY, m_vecSeatOffest[0]); - WriteFloat(MSG_ENTITY, m_vecSeatOffest[1]); - WriteFloat(MSG_ENTITY, m_vecSeatOffest[2]); - } - - if (flSendFlags & VEHFL_ORIGIN) { - WriteCoord(MSG_ENTITY, origin[0]); - WriteCoord(MSG_ENTITY, origin[1]); - WriteCoord(MSG_ENTITY, origin[2]); - } - - if (flSendFlags & VEHFL_ANGLES) { - WriteFloat(MSG_ENTITY, angles[0]); - WriteFloat(MSG_ENTITY, angles[1]); - WriteFloat(MSG_ENTITY, angles[2]); - } - - if (flSendFlags & VEHFL_VELOCITY) { - WriteFloat(MSG_ENTITY, velocity[0]); - WriteFloat(MSG_ENTITY, velocity[1]); - WriteFloat(MSG_ENTITY, velocity[2]); - } - - if (flSendFlags & VEHFL_TURNING) - WriteFloat(MSG_ENTITY, m_flTurn); - - if (flSendFlags & VEHFL_FLAGS) - WriteFloat(MSG_ENTITY, flags); - - return true; -} -#endif - -void -prop_vehicle_driveable::Spawned(void) -{ - super::Spawned(); - -#ifdef SERVER - Sound_Precache("prop_vehicle_driveable.bounce"); -#endif -} \ No newline at end of file +} + +float +prop_vehicle_driveable::SendEntity(entity ePVSent, float flSendFlags) +{ + WriteByte(MSG_ENTITY, ENT_VEH_4WHEEL); + WriteFloat(MSG_ENTITY, flSendFlags); + + if (!modelindex) + return (false); + + if (flSendFlags & VEHFL_DRIVER) { + WriteEntity(MSG_ENTITY, m_eDriver); + } + + if (flSendFlags & VEHFL_MODELINDEX) { + WriteShort(MSG_ENTITY, modelindex); + WriteFloat(MSG_ENTITY, m_vecSeatOffest[0]); + WriteFloat(MSG_ENTITY, m_vecSeatOffest[1]); + WriteFloat(MSG_ENTITY, m_vecSeatOffest[2]); + } + + if (flSendFlags & VEHFL_ORIGIN) { + WriteCoord(MSG_ENTITY, origin[0]); + WriteCoord(MSG_ENTITY, origin[1]); + WriteCoord(MSG_ENTITY, origin[2]); + } + + if (flSendFlags & VEHFL_ANGLES) { + WriteFloat(MSG_ENTITY, angles[0]); + WriteFloat(MSG_ENTITY, angles[1]); + WriteFloat(MSG_ENTITY, angles[2]); + } + + if (flSendFlags & VEHFL_VELOCITY) { + WriteFloat(MSG_ENTITY, velocity[0]); + WriteFloat(MSG_ENTITY, velocity[1]); + WriteFloat(MSG_ENTITY, velocity[2]); + } + + if (flSendFlags & VEHFL_TURNING) + WriteFloat(MSG_ENTITY, m_flTurn); + + if (flSendFlags & VEHFL_FLAGS) + WriteFloat(MSG_ENTITY, flags); + + return true; +} +#endif + +void +prop_vehicle_driveable::Spawned(void) +{ + super::Spawned(); + + m_iVehicleFlags |= VHF_FROZEN; + hitcontentsmaski = CONTENTBIT_BODY | CONTENTBITS_POINTSOLID | CONTENTBIT_VEHICLECLIP; + + SpawnWheels(); + + customphysics = Physics; + +#ifdef SERVER + Sound_Precache("prop_vehicle_driveable.bounce"); +#endif +} diff --git a/src/gs-entbase/shared/speaker.qc b/src/gs-entbase/shared/speaker.qc index f8b672f4..70184ea2 100644 --- a/src/gs-entbase/shared/speaker.qc +++ b/src/gs-entbase/shared/speaker.qc @@ -175,6 +175,11 @@ speaker::Respawn(void) if (HasSpawnFlags(SPEAKFL_SILENT) == false) { ScheduleThink(Announce, 10.0f); } + + SetSize([0,0,0], [0,0,0]); + SetSolid(SOLID_NOT); + SetMovetype(MOVETYPE_NONE); + customphysics = __NULL__; } void @@ -240,4 +245,4 @@ speaker::ReceiveEntity(float flNew, float flChanged) READENTITY_COORD(origin[2], MONFL_CHANGED_ORIGIN_Z) SetOrigin(origin); } -#endif \ No newline at end of file +#endif diff --git a/src/menu-fn/background.qc b/src/menu-fn/background.qc deleted file mode 100644 index 510870bd..00000000 --- a/src/menu-fn/background.qc +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2016-2022 Vera Visions LLC. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -void -drawpic_flip(vector pos, string mat, vector size, vector color, float alpha) -{ - drawsubpic(pos, size, mat, [1,0], [-1,1], color, alpha, 0); -} - -static int g_bg_check; - -void -Background_WON(void) -{ - /* handle missing backgrounds gracefully */ - if (!g_bg_check) { - if (whichpack(strcat(g_bmp[SPLASH], ".bmp"))) { - g_bg_check = 1; - } else { - g_bg_check = 2; /* missing */ - } - } - - if (g_bg_check == 1) { - drawpic([g_menuofs[0],g_menuofs[1]], g_bmp[SPLASH], - [640,480], [1,1,1], 1.0f); - } else { - drawfill([g_menuofs[0],g_menuofs[1]], [640, 480], [0.1,0.1,0.1], 1.0f); - } - - /* just some silly widescreen extension hack that could apply to some games */ -#if 0 - drawpic_flip([g_menuofs[0] - 640,g_menuofs[1]], g_bmp[SPLASH], - [640,480], [1,1,1], 1.0f); - drawpic_flip([g_menuofs[0] + 640,g_menuofs[1]], g_bmp[SPLASH], - [640,480], [1,1,1], 1.0f); -#endif -} - -typedef struct -{ - string strMat; - vector vecSize; - vector vecPos; -} backResource_t; - -backResource_t g_back800[] = -{ - {"resource/background/800_1_a_loading",[256,256,0],[0,0,0]}, - {"resource/background/800_1_b_loading",[256,256,0],[256,0,0]}, - {"resource/background/800_1_c_loading",[256,256,0],[512,0,0]}, - {"resource/background/800_1_d_loading",[32,256,0],[768,0,0]}, - {"resource/background/800_2_a_loading",[256,256,0],[0,256,0]}, - {"resource/background/800_2_b_loading",[256,256,0],[256,256,0]}, - {"resource/background/800_2_c_loading",[256,256,0],[512,256,0]}, - {"resource/background/800_2_d_loading",[32,256,0],[768,256,0]}, - {"resource/background/800_3_a_loading",[256,88,0],[0,512,0]}, - {"resource/background/800_3_b_loading",[256,88,0],[256,512,0]}, - {"resource/background/800_3_c_loading",[256,88,0],[512,512,0]}, - {"resource/background/800_3_d_loading",[32,88,0],[768,512,0]} -}; - -void -Background_Steam(void) -{ - for (int i = 0; i < g_back800.length; i++) { - vector pos = [0.0f, 0.0f, 0.0f]; - vector size = [0.0f, 0.0f, 0.0f]; - - /* scale down 800x600 to 640x480 */ - size = g_back800[i].vecSize * 0.8f; - pos[0] = g_menuofs[0] + (g_back800[i].vecPos[0] * 0.8f); - pos[1] = g_menuofs[1] + (g_back800[i].vecPos[1] * 0.8f); - - drawpic(pos, \ - g_back800[i].strMat, \ - size, \ - [1,1,1], \ - 1.0f); - } -} diff --git a/src/menu-fn/defs.h b/src/menu-fn/defs.h index 67382755..fb8eddce 100644 --- a/src/menu-fn/defs.h +++ b/src/menu-fn/defs.h @@ -31,11 +31,11 @@ var bool autocvar_menu_steambg = false; #define DRAWFLAG_ADDITIVE 1 /* Basic Menu Globals */ -int g_vidsize[2]; -int g_menuofs[2]; -int g_mousepos[2]; +vector g_vidsize; +vector g_menuofs; +vector g_mousepos; vector g_logosize; -int g_lastmousepos[2]; +vector g_lastmousepos; int g_active; float frametime; var int g_background = FALSE; @@ -48,7 +48,7 @@ font_s font_console; font_s font_arial; font_s font_label_p; -var int autocvar_menu_helptext_size = 11; +var int autocvar_menu_helptext_size = 13; #define HELPTXT_SIZE autocvar_menu_helptext_size @@ -130,4 +130,4 @@ bool mp_connected(void) { return (!autocvar__menu_singleplayer && clientstate() == 2 && !g_background) ? true : false; -} \ No newline at end of file +} diff --git a/src/menu-fn/entry.qc b/src/menu-fn/entry.qc index 72c16ecd..e615bc9d 100644 --- a/src/menu-fn/entry.qc +++ b/src/menu-fn/entry.qc @@ -22,7 +22,7 @@ var bool g_input_received = false; /* r_autoscale forces vid_conautoscale to be one of 4 integer values. * this is due to vid_conautoscale 0 scaling with in floating point... which * in turns results in skipped rows/columns and shimmering. */ -var int autocvar_r_autoscale = TRUE; +var int autocvar_r_autoscale = false; var int autocvar_r_pixelscale = FALSE; void Menu_AutoScale(void) @@ -66,7 +66,7 @@ Menu_GammaHack(void) bool Menu_HasStartupVideos(void) { - if (Platform_FileInCurrentGamedir("media/valve.avi")) + if (fileExists("media/valve.avi")) return true; return false; @@ -103,7 +103,6 @@ m_init(void) cvar_set("rate", "30000"); } - Platform_RegisterCommands(); Font_Load("fonts/fontcon.font", font_console); Font_Load("fonts/menu_label.font", font_label); @@ -113,12 +112,11 @@ m_init(void) localcmd("plug_load ffmpeg\n"); + Platform_Init(); + /* don't precache btns_main.bmp directly any more. */ CMainButton_InitSheets(); - - GameLibrary_Init(); Strings_Init(); - MapLibrary_Init(); main_init(); Colors_Init(); @@ -166,6 +164,7 @@ m_init(void) void Menu_RendererRestarted(string rendererdesc) { + Platform_RendererRestarted(); CMainButton_InitSheets(); Menu_AutoScale(); Menu_GammaHack(); @@ -262,21 +261,7 @@ m_draw(vector screensize) return; } - /* when ingame, we'll draw a slight black tint... */ - if (clientstate() == 2) { - /* ...unless we're in background map mode. */ - if (!g_background) - drawpic([0,0], "menutint", screensize, [1,1,1], 1.0f); - } else { - /* clear screen */ - drawfill([0,0], screensize, [0,0,0], 1.0f); - - /* draw either WON or Steam background */ - if (autocvar_menu_steambg == false) - Background_WON(); - else - Background_Steam(); - } + Background_Draw((g_vidsize / 2) - [320,240], [640,480]); /* water mark for version info */ const string ver = "Nuclide (build " __DATE__ ")"; @@ -360,7 +345,7 @@ m_display(void) g_active = TRUE; setkeydest(KEY_MENU); setmousetarget(TARGET_MENU); - setcursormode(TRUE, "gfx/cursor"); + setcursormode(TRUE, "gfx/icon16/cursor"); } /* diff --git a/src/menu-fn/includes.src b/src/menu-fn/includes.src index 8f68e233..b9b5209a 100644 --- a/src/menu-fn/includes.src +++ b/src/menu-fn/includes.src @@ -68,7 +68,6 @@ m_updates.qc m_intro.qc m_main.qc menu.qc -background.qc ../platform/includes.src diff --git a/src/menu-fn/m_loadgame.qc b/src/menu-fn/m_loadgame.qc index edcf7d58..3b120a12 100644 --- a/src/menu-fn/m_loadgame.qc +++ b/src/menu-fn/m_loadgame.qc @@ -14,9 +14,6 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -string *g_savegames; -int g_savegame_count; - CWidget fn_loadgame; CMainButton lg_btnLoad; CMainButton lg_btnDelete; @@ -30,14 +27,14 @@ void lg_btnload(void) { int i = lg_lbSaves.GetSelected(); - localcmd(sprintf("load %s\n", g_savegames[i])); + localcmd(sprintf("load %s\n", Saves_GetInfo(i, SAVEINFO_NAME))); } void lg_btnunsave(void) { int i = lg_lbSaves.GetSelected(); - localcmd(sprintf("unsavegame %s\n", g_savegames[i])); + localcmd(sprintf("unsavegame %s\n", Saves_GetInfo(i, SAVEINFO_NAME))); } void @@ -58,7 +55,7 @@ lg_btncancel_start(void) void lg_lbsaves_changed(int val) { - + } void up_sbsaves_changed(int val) @@ -66,21 +63,19 @@ up_sbsaves_changed(int val) lg_lbSaves.SetScroll(val); } + + + + void menu_loadgame_refreshsaves(void) { - searchhandle searchy; lg_lbSaves.Clear(); - searchy = search_begin("saves/*/info.fsv", SEARCH_NAMESORT, TRUE); - g_savegame_count = search_getsize(searchy); - g_savegames = memalloc(sizeof(string) * g_savegame_count); - for (int i = 0; i < g_savegame_count; i++) { - string fullpath = search_getfilename(searchy, i); - g_savegames[i] = substring(fullpath, 6, strlen(fullpath) - 15); - precache_pic(sprintf("saves/%s/screeny.tga", g_savegames[i])); - lg_lbSaves.AddEntry(g_savegames[i]); + + for (int i = 0; i < Saves_GetSaveCount(); i++) { + lg_lbSaves.AddEntry(Saves_GetInfo(i, SAVEINFO_NAME)); } - search_end(searchy); + lg_lbSaves.SetSelected(0, TRUE); } @@ -125,7 +120,7 @@ menu_loadgame_init(void) lg_sbSaves.SetCallback(up_sbsaves_changed); lg_sbSaves.SetMax(0); Widget_Add(fn_loadgame, lg_sbSaves); - + lg_frPreview = spawn(CFrame); lg_frPreview.SetPos(390,140); lg_frPreview.SetSize(220,165); @@ -145,7 +140,7 @@ menu_loadgame_draw(void) } int i = lg_lbSaves.GetSelected(); - drawpic([g_menuofs[0]+390,g_menuofs[1]+140], sprintf("saves/%s/screeny.tga", g_savegames[i]),[220,165], [1,1,1], 1.0f, 1); + drawpic([g_menuofs[0]+390,g_menuofs[1]+140], Saves_GetInfo(i, SAVEINFO_PREVIEW),[220,165], [1,1,1], 1.0f, 1); } void diff --git a/src/menu-vgui/desktop.qc b/src/menu-vgui/desktop.qc old mode 100755 new mode 100644 index 39adea4e..89ad8747 --- a/src/menu-vgui/desktop.qc +++ b/src/menu-vgui/desktop.qc @@ -26,6 +26,7 @@ void Desktop_Init ( void ) static CUIMenuButton btnMViewer; static CUIMenuButton btnResume; static CUIMenuButton btnDisconnect; + static CUIMenuButton btnMods; static void Desktop_ResumeGame ( void ) { m_toggle( 0 ); @@ -43,7 +44,7 @@ void Desktop_Init ( void ) btnNewgame.SetPos( '32 64' ); btnNewgame.SetFunc( UI_NewGame_Show ); btnNewgame.FlagRemove( MBUTTON_SHOWSP | MBUTTON_SHOWMP ); - btnNewgame.SetIcon( "textures/ui/icons/desktop" ); + btnNewgame.SetIcon( "gfx/icon16/new" ); btnDisconnect = spawn( CUIMenuButton ); btnDisconnect.SetTitle( "Disconnect" ); @@ -51,54 +52,63 @@ void Desktop_Init ( void ) btnDisconnect.SetPos( '32 64' ); btnDisconnect.SetFunc( Desktop_DisconnectGame ); btnDisconnect.FlagRemove( MBUTTON_SHOWOFFLINE ); - btnDisconnect.SetIcon( "textures/ui/icons/disconnect" ); + btnDisconnect.SetIcon( "gfx/icon16/disconnect" ); btnLoadgame = spawn( CUIMenuButton ); btnLoadgame.SetTitle( "Load Game" ); btnLoadgame.SetSize( '128 24' ); btnLoadgame.SetPos( '32 96' ); - btnLoadgame.SetIcon( "textures/ui/icons/folder" ); + btnLoadgame.SetIcon( "gfx/icon16/book_edit" ); + btnLoadgame.SetFunc( UI_LoadGame_Show ); btnFindserver = spawn( CUIMenuButton ); btnFindserver.SetTitle( "Find Servers" ); btnFindserver.SetSize( '128 24' ); btnFindserver.SetPos( '32 128' ); btnFindserver.SetFunc( UI_FindServers_Show ); - btnFindserver.SetIcon( "textures/ui/icons/servers" ); + btnFindserver.SetIcon( "gfx/icon16/world_go" ); btnCreateserver = spawn( CUIMenuButton ); btnCreateserver.SetTitle( "Create Server" ); btnCreateserver.SetSize( '128 24' ); btnCreateserver.SetPos( '32 160' ); btnCreateserver.SetFunc( UI_CreateServer_Show ); - btnCreateserver.SetIcon( "textures/ui/icons/server-new" ); + btnCreateserver.SetIcon( "gfx/icon16/server_add" ); + + btnMods = spawn( CUIMenuButton ); + btnMods.SetTitle( "Custom Game" ); + btnMods.SetSize( '128 24' ); + btnMods.SetPos( '32 192' ); + btnMods.SetIcon( "gfx/icon16/rainbow" ); + btnMods.SetFunc( UI_CustomGame_Show ); + btnMods.FlagRemove( MBUTTON_SHOWSP | MBUTTON_SHOWMP ); btnOptions = spawn( CUIMenuButton ); btnOptions.SetTitle( "Options" ); btnOptions.SetSize( '128 24' ); - btnOptions.SetPos( '32 192' ); - btnOptions.SetIcon( "textures/ui/icons/gear" ); + btnOptions.SetPos( '32 224' ); + btnOptions.SetIcon( "gfx/icon16/cog" ); btnQuit = spawn( CUIMenuButton ); btnQuit.SetTitle( "Quit Game" ); btnQuit.SetSize( '128 24' ); - btnQuit.SetPos( '32 224' ); + btnQuit.SetPos( '32 256' ); btnQuit.SetFunc( UI_QuitGame_Show ); - btnQuit.SetIcon( "textures/ui/icons/cancel" ); + btnQuit.SetIcon( "gfx/icon16/stop" ); btnMPlayer = spawn( CUIMenuButton ); btnMPlayer.SetTitle( "Music Player" ); btnMPlayer.SetSize( '128 24' ); btnMPlayer.SetPos( '32 288' ); btnMPlayer.SetFunc( UI_MusicPlayer_Show ); - btnMPlayer.SetIcon( "textures/ui/icons/cd" ); + btnMPlayer.SetIcon( "gfx/icon16/ipod" ); btnMViewer = spawn( CUIMenuButton ); btnMViewer.SetTitle( "Model Viewer" ); btnMViewer.SetSize( '128 24' ); btnMViewer.SetPos( '32 320' ); btnMViewer.SetFunc( UI_ModelViewer_Show ); - btnMViewer.SetIcon( "textures/ui/icons/hdd" ); + btnMViewer.SetIcon( "gfx/icon16/images" ); btnResume = spawn( CUIMenuButton ); btnResume.SetTitle( "Resume Game" ); @@ -106,6 +116,7 @@ void Desktop_Init ( void ) btnResume.SetPos( '32 384' ); btnResume.SetFunc( Desktop_ResumeGame ); btnResume.FlagRemove( MBUTTON_SHOWOFFLINE ); + btnResume.SetIcon( "gfx/icon16/control_play" ); g_uiDesktop.Add( btnNewgame ); g_uiDesktop.Add( btnLoadgame ); @@ -117,9 +128,16 @@ void Desktop_Init ( void ) g_uiDesktop.Add( btnMViewer ); g_uiDesktop.Add( btnResume ); g_uiDesktop.Add( btnDisconnect ); + g_uiDesktop.Add( btnMods ); } void Desktop_Draw ( void ) { g_uiDesktop.Draw(); } + +void Desktop_CanvasChanged ( void ) +{ + g_uiDesktop.Reposition(); +} + diff --git a/src/menu-vgui/includes.src b/src/menu-vgui/includes.src index 3220828b..48c94150 100644 --- a/src/menu-vgui/includes.src +++ b/src/menu-vgui/includes.src @@ -7,16 +7,17 @@ ../platform/defs.h defs.h ../vgui/include.src -background.qc loading.qc main.h ui_console.qc ui_newgame.qc ui_quitgame.qc ui_createserver.qc +ui_customgame.qc ui_findservers.qc ui_musicplayer.qc ui_modelviewer.qc +ui_loadgame.qc desktop.qc main.qc ../platform/includes.src diff --git a/src/menu-vgui/loading.qc b/src/menu-vgui/loading.qc old mode 100755 new mode 100644 index e0653639..a7ee442a --- a/src/menu-vgui/loading.qc +++ b/src/menu-vgui/loading.qc @@ -14,12 +14,23 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +VGUILoadingPanel loadingPanel; + void Loading_Draw ( vector vecSize ) { - drawpic( [ 0, 0 ], "textures/gfx/background", vecSize, [ 1, 1, 1 ], 1.0f ); + g_vidsize = vecSize; + + if (!loadingPanel) { + loadingPanel = spawn(VGUILoadingPanel); + } + +#if 1 + loadingPanel.Draw(); + loadingPanel.UpdateProgress(); +#else vector vecLoadingSize = [ 256, 96 ]; - vector vecLoadingPos = ( g_vidsize / 2 ) - ( vecLoadingSize / 2 ); + vector vecLoadingPos = ( vecSize / 2 ) - ( vecLoadingSize / 2 ); drawfill( vecLoadingPos, vecLoadingSize, UI_MAINCOLOR, UI_MAINALPHA ); drawfill( vecLoadingPos, [vecLoadingSize[0], 1], [1,1,1], 0.5f ); @@ -27,4 +38,5 @@ void Loading_Draw ( vector vecSize ) drawfill( vecLoadingPos + [ 0, 1], [1, vecLoadingSize[1] - 2], [1,1,1], 0.5f ); drawfill( vecLoadingPos + [ vecLoadingSize[0] - 1, 1], [1, vecLoadingSize[1] - 2], [0,0,0], 0.5f ); Font_DrawText( vecLoadingPos + [ 8, 8 ], "Loading...", g_fntDefault ); +#endif } diff --git a/src/menu-vgui/main.qc b/src/menu-vgui/main.qc index 21557046..fa153849 100644 --- a/src/menu-vgui/main.qc +++ b/src/menu-vgui/main.qc @@ -14,7 +14,7 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -var int autocvar_r_autoscale = TRUE; +var int autocvar_r_autoscale = false; void Menu_AutoScale(void) @@ -22,6 +22,7 @@ Menu_AutoScale(void) if (autocvar_r_autoscale) { /* override for vid_conautoscales */ vector psize = getproperty(VF_SCREENPSIZE); + if (psize[1] >= (480 * 4)) { cvar_set("vid_conautoscale", "4"); } else if (psize[1] >= (480 * 3)) { @@ -37,10 +38,11 @@ Menu_AutoScale(void) void m_init(void) { + Platform_Init(); UISystem_Init(); - Background_Init(); Desktop_Init(); + registercommand("console"); registercommand("menu_quit"); registercommand("menu_music"); registercommand("map_background"); @@ -50,7 +52,7 @@ m_init(void) void Menu_RendererRestarted(string renderer) { - localcmd("menu_restart\n"); + Platform_RendererRestarted(); Menu_AutoScale(); } @@ -70,6 +72,7 @@ m_draw(vector screensize) g_menuofs[0] = (g_vidsize[0] / 2) - 320; g_menuofs[1] = (g_vidsize[1] / 2) - 240; Menu_AutoScale(); + Desktop_CanvasChanged(); } g_background = cvar("_background"); @@ -79,7 +82,7 @@ m_draw(vector screensize) if (getkeydest() != KEY_MENU) { setkeydest(KEY_MENU); setmousetarget(TARGET_MENU); - setcursormode(TRUE, "gfx/cursor"); + setcursormode(TRUE, "gfx/icon16/cursor"); } } @@ -97,10 +100,24 @@ m_draw(vector screensize) lasttime = time; g_vidsize = screensize; - Background_Draw(screensize); + + Background_Draw([0,0], g_vidsize); Desktop_Draw(); } +void +m_drawloading(vector screensize, float opaque) +{ + vector pos; + pos = (screensize / 2) - [32,32]; + + if (opaque || (clientstate() != 2)) { + Background_Draw([0,0], screensize); + } + + Loading_Draw(screensize); +} + float Menu_InputEvent (float evtype, float scanx, float chary, float devid) { @@ -133,7 +150,7 @@ m_display(void) g_active = TRUE; setkeydest(KEY_MENU); setmousetarget(TARGET_MENU); - setcursormode(TRUE, "gfx/cursor"); + setcursormode(TRUE, "gfx/icon16/cursor"); } /* @@ -170,6 +187,14 @@ m_consolecommand(string cmd) int c = (int)tokenize(cmd); switch (argv(0)) { + case "console": + static VGUIConsole consoleWindow; + + if (!consoleWindow) + consoleWindow = spawn(VGUIConsole); + + g_uiDesktop.Add( consoleWindow ); + break; case "menu_quit": UI_QuitGame_Show(); break; diff --git a/src/menu-vgui/ui_createserver.qc b/src/menu-vgui/ui_createserver.qc old mode 100755 new mode 100644 index 79b176d6..a4b60f57 --- a/src/menu-vgui/ui_createserver.qc +++ b/src/menu-vgui/ui_createserver.qc @@ -48,7 +48,7 @@ void UI_CreateServer_Show ( void ) lsbMaps.SetOffset( scrlMaps.GetValue(), FALSE ); } static void CreateServer_Scrolled ( void ) { - scrlMaps.SetValue( lsbMaps.GetOffset(), FALSE ); + scrlMaps.SetValue( lsbMaps.GetOffset() ); } if ( !g_iCreateServerInitialized ) { @@ -56,20 +56,19 @@ void UI_CreateServer_Show ( void ) winCreate = spawn( CUIWindow ); winCreate.SetTitle( "Create Server" ); winCreate.SetSize( '338 385' ); - winCreate.SetIcon( "textures/ui/icons/server-new" ); + winCreate.SetIcon( "gfx/icon16/server_add" ); - searchhandle shMaps = search_begin( "maps/*.bsp", SEARCH_NAMESORT, TRUE ); lsbMaps = spawn( CUIList ); lsbMaps.SetSize( '128 306' ); lsbMaps.SetPos( '175 32 ' ); - lsbMaps.SetItemCount( search_getsize( shMaps ) ); + lsbMaps.SetItemCount( MapLibrary_GetMapCount() ); lsbMaps.CallOnScroll( CreateServer_Scrolled ); lsbMaps.SetSelected( 0 ); lsbMaps.AddItem( "< Random Map >" ); - for ( int i = 0; i < search_getsize( shMaps ); i++ ) { - string strMap = search_getfilename( shMaps, i ); - lsbMaps.AddItem( substring( strMap, 5, strlen( strMap ) - 9 ) ); + for ( int i = 0; i < MapLibrary_GetMapCount(); i++ ) { + string strMap = MapLibrary_GetInfo(i, MAPINFO_NAME); + lsbMaps.AddItem( strMap ); //lsbMaps.AddItem( search_getfilename( shMaps, i ) ); } @@ -109,7 +108,7 @@ void UI_CreateServer_Show ( void ) txbMaxplayers = spawn( CUITextBox ); txbMaxplayers.SetPos( [ 20, 102 ] ); txbMaxplayers.SetSize( [ 124, 24 ] ); - txbMaxplayers.SetText( cvar_string( "sv_playerslots" ) ); + txbMaxplayers.SetText( cvar_string( "sv_playerslots" ) != "1" ? cvar_string( "sv_playerslots" ) : "8" ); lblPassword = spawn( CUILabel ); lblPassword.SetPos( '20 136' ); @@ -131,7 +130,6 @@ void UI_CreateServer_Show ( void ) winCreate.Add( txbMaxplayers ); winCreate.Add( lblPassword ); winCreate.Add( txbPassword ); - search_end( shMaps ); } winCreate.Show(); diff --git a/src/menu-vgui/ui_customgame.qc b/src/menu-vgui/ui_customgame.qc new file mode 100644 index 00000000..f9818e42 --- /dev/null +++ b/src/menu-vgui/ui_customgame.qc @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2016-2022 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +int g_iCustomGameInitialized; + +void UI_CustomGame_Show ( void ) +{ + static CUIWindow winCustomGame; + static CUIList lsbGames; + static CUIScrollbar scrlGames; + static CUIButton btnLoad; + + static void CustomGame_Play ( void ) { + GameLibrary_Activate(lsbGames.GetSelected()); + } + + static void CustomGame_ScrollUpdate ( void ) { + scrlGames.SetValue( lsbGames.GetOffset(), FALSE ); + } + static void CustomGame_ListUpdate ( void ) { + lsbGames.SetOffset( scrlGames.GetValue(), FALSE ); + } + + if ( !g_iCustomGameInitialized ) { + g_iCustomGameInitialized = TRUE; + + GameLibrary_InitCustom(); + + winCustomGame = spawn( CUIWindow ); + winCustomGame.SetTitle( "Custom Game" ); + winCustomGame.SetSize( [256,180] ); + winCustomGame.SetIcon( "gfx/icon16/rainbow" ); + + lsbGames = spawn( CUIList ); + lsbGames.SetSize( [192, 96] ); + lsbGames.SetPos( [8, 32] ); + lsbGames.SetItemCount( GameLibrary_GetGameCount() ); + lsbGames.CallOnScroll( CustomGame_ScrollUpdate ); + + for ( int i = 0; i < GameLibrary_GetGameCount(); i++ ) { + lsbGames.AddItem( GameLibrary_GetGameInfo(i, GAMEINFO_TITLE) ); + } + + scrlGames = spawn( CUIScrollbar ); + scrlGames.SetLength( 96 ); + scrlGames.SetPos( [201,32] ); + scrlGames.SetMin( 0 ); + scrlGames.SetStep( 1 ); + scrlGames.SetMax( lsbGames.GetMaxVisibleItems() ); + scrlGames.CallOnChange( CustomGame_ListUpdate ); + + btnLoad = spawn( CUIButton ); + btnLoad.SetTitle( "Load" ); + btnLoad.SetIcon( "gfx/icon16/control_play" ); + btnLoad.SetPos( [8,132] ); + btnLoad.SetSize([64,24]); + btnLoad.SetFunc( CustomGame_Play ); + + g_uiDesktop.Add( winCustomGame ); + winCustomGame.Add( lsbGames ); + winCustomGame.Add( scrlGames ); + winCustomGame.Add( btnLoad ); + } + + winCustomGame.Show(); + winCustomGame.SetPos( ( g_vidsize / 2 ) - ( winCustomGame.GetSize() / 2 ) ); +} diff --git a/src/menu-vgui/ui_findservers.qc b/src/menu-vgui/ui_findservers.qc old mode 100755 new mode 100644 index ba3dc774..df51b95e --- a/src/menu-vgui/ui_findservers.qc +++ b/src/menu-vgui/ui_findservers.qc @@ -25,7 +25,7 @@ void UI_FindServers_Show ( void ) winFind = spawn( CUIWindow ); winFind.SetTitle( "Find Servers" ); winFind.SetSize( '600 400' ); - winFind.SetIcon( "textures/ui/icons/servers" ); + winFind.SetIcon( "gfx/icon16/world" ); g_uiDesktop.Add( winFind ); } diff --git a/src/menu-vgui/ui_loadgame.qc b/src/menu-vgui/ui_loadgame.qc new file mode 100644 index 00000000..7a3e094e --- /dev/null +++ b/src/menu-vgui/ui_loadgame.qc @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016-2022 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +int g_iLoadGameInitialized; + +void UI_LoadGame_Show ( void ) +{ + static CUIWindow winLoadGame; + static CUIList lsbSaves; + static CUIScrollbar scrlSaves; + static CUIButton btnLoad; + + static void LoadGame_Play ( void ) { + string strSong; + strSong = lsbSaves.GetItem( lsbSaves.GetSelected() ); + localcmd( sprintf( "load %s\n", strSong) ); + } + + static void LoadGame_ScrollUpdate ( void ) { + scrlSaves.SetValue( lsbSaves.GetOffset(), FALSE ); + } + static void LoadGame_ListUpdate ( void ) { + lsbSaves.SetOffset( scrlSaves.GetValue(), FALSE ); + } + + if ( !g_iLoadGameInitialized ) { + g_iLoadGameInitialized = TRUE; + winLoadGame = spawn( CUIWindow ); + winLoadGame.SetTitle( "Load Game" ); + winLoadGame.SetSize( [256,180] ); + winLoadGame.SetIcon( "gfx/icon16/music" ); + + lsbSaves = spawn( CUIList ); + lsbSaves.SetSize( [192, 96] ); + lsbSaves.SetPos( [8, 32] ); + lsbSaves.SetItemCount( Saves_GetSaveCount() ); + lsbSaves.CallOnScroll( LoadGame_ScrollUpdate ); + + for ( int i = 0; i < Saves_GetSaveCount(); i++ ) { + lsbSaves.AddItem( Saves_GetInfo(i, SAVEINFO_NAME) ); + } + + scrlSaves = spawn( CUIScrollbar ); + scrlSaves.SetLength( 96 ); + scrlSaves.SetPos( [201,32] ); + scrlSaves.SetMin( 0 ); + scrlSaves.SetStep( 1 ); + scrlSaves.SetMax( lsbSaves.GetMaxVisibleItems() ); + scrlSaves.CallOnChange( LoadGame_ListUpdate ); + + btnLoad = spawn( CUIButton ); + btnLoad.SetTitle( "Load" ); + btnLoad.SetIcon( "gfx/icon16/book_edit" ); + btnLoad.SetPos( [8,132] ); + btnLoad.SetSize([64,24]); + btnLoad.SetFunc( LoadGame_Play ); + + g_uiDesktop.Add( winLoadGame ); + winLoadGame.Add( lsbSaves ); + winLoadGame.Add( scrlSaves ); + winLoadGame.Add( btnLoad ); + } + + winLoadGame.Show(); + winLoadGame.SetPos( ( g_vidsize / 2 ) - ( winLoadGame.GetSize() / 2 ) ); +} diff --git a/src/menu-vgui/ui_modelviewer.qc b/src/menu-vgui/ui_modelviewer.qc index c7ab368c..b55289fb 100644 --- a/src/menu-vgui/ui_modelviewer.qc +++ b/src/menu-vgui/ui_modelviewer.qc @@ -48,6 +48,9 @@ void AngleVectors ( vector angles ) v_up[2] = cr*cp; } +string(float modidx, float framenum) frametoname = #0; +.float modelindex; + void UI_ModelViewer_Show ( void ) { static entity eModel; @@ -80,17 +83,25 @@ void UI_ModelViewer_Show ( void ) viewModel.Set3DPos( [0,0,0] ); } static void UI_ModelViewer_SetFrame( int iFrame ) { + float maxFrame = modelframecount(eModel.modelindex) - 1; eModel.frame = (float)iFrame; - lblSeqFrame.SetTitle( sprintf( "Frame: %i", iFrame ) ); + + if (eModel.frame > maxFrame) { + eModel.frame = (maxFrame); + } + + if (eModel.frame < 0) { + eModel.frame = 0; + } + + lblSeqFrame.SetTitle( sprintf( "Frame %d: %s", eModel.frame, frametoname(eModel.modelindex, eModel.frame) ) ); eModel.frame1time = 0; } static void UI_ModelViewer_SetFrameP( void ) { - UI_ModelViewer_SetFrame( ++eModel.frame ); + UI_ModelViewer_SetFrame( eModel.frame + 1 ); } static void UI_ModelViewer_SetFrameM( void ) { - if ( eModel.frame ) { - UI_ModelViewer_SetFrame( --eModel.frame ); - } + UI_ModelViewer_SetFrame( eModel.frame - 1 ); } static void UI_ModelViewer_SetModel( string strModel ) { setmodel( eModel, strModel ); @@ -111,10 +122,10 @@ void UI_ModelViewer_Show ( void ) if ( chkGround.GetValue() == TRUE ) { R_BeginPolygon( "", 0, FALSE ); - R_PolygonVertex( [ 64, -64, 0 ], '1 0', [1,1,1], 1.0f ); // Top Right - R_PolygonVertex( [ -64, -64, 0 ], '0 0', [1,1,1], 1.0f ); // Top left - R_PolygonVertex( [ -64, 64, 0 ], '0 1', [1,1,1], 1.0f ); // Bottom left - R_PolygonVertex( [ 64, 64, 0 ], '1 1', [1,1,1], 1.0f ); // Bottom right + R_PolygonVertex( [ 64, -64, 0 ], [1,0], [1,1,1], 1.0f ); // Top Right + R_PolygonVertex( [ -64, -64, 0 ], [0,0], [1,1,1], 1.0f ); // Top left + R_PolygonVertex( [ -64, 64, 0 ], [0,1], [1,1,1], 1.0f ); // Bottom left + R_PolygonVertex( [ 64, 64, 0 ], [1,1], [1,1,1], 1.0f ); // Bottom right R_EndPolygon(); } @@ -249,7 +260,7 @@ void UI_ModelViewer_Show ( void ) winViewer.SetMaxSize( [ 9999, 9999 ] ); winViewer.SetStyleMask( VGUIWindowStyleDefault | VGUIWindowResizeable ); winViewer.SetPos( [ 172, 64 ] ); - winViewer.SetIcon( "textures/ui/icons/hdd" ); + winViewer.SetIcon( "gfx/icon16/images" ); winViewer.CallOnResize( UI_ModelViewer_Resize ); picBackground = spawn( CUIPic ); @@ -287,11 +298,14 @@ void UI_ModelViewer_Show ( void ) lblSeqFrame = spawn( CUILabel ); lblSeqFrame.SetTitle( "Frame: 0" ); + lblSeqFrame.SetSize([550,16]); btnSeqNext = spawn( CUIButton ); btnSeqNext.SetTitle( ">>" ); + btnSeqNext.SetSize([48,24]); btnSeqNext.SetFunc( UI_ModelViewer_SetFrameP ); btnSeqPrev = spawn( CUIButton ); btnSeqPrev.SetTitle( "<<" ); + btnSeqPrev.SetSize([48,24]); btnSeqPrev.SetFunc( UI_ModelViewer_SetFrameM ); searchhandle shModels = search_begin( "models/*.mdl:models/*.vvm:models/*/*.mdl:models/*/*.vvm:models/*/*/*.mdl:models/*/*/*.vvm:models/*/*/*/*.mdl:models/*/*/*/*.vvm", SEARCH_NAMESORT | SEARCH_MULTISEARCH, TRUE ); @@ -301,7 +315,7 @@ void UI_ModelViewer_Show ( void ) for ( int i = 0; i < search_getsize( shModels ); i++ ) { string strAdd = search_getfilename( shModels, i ); - lstModels.AddItem( substring( strAdd , 6, strlen( strAdd ) - 6 ) ); + lstModels.AddItem( substring( strAdd , 7, -1 ) ); } search_end( shModels ); @@ -316,7 +330,7 @@ void UI_ModelViewer_Show ( void ) btnLoadModel = spawn( CUIButton ); btnLoadModel.SetTitle( "Load Selected" ); btnLoadModel.SetFunc( UI_ModelViewer_LoadSelected ); - btnLoadModel.SetSize( '192 24' ); + btnLoadModel.SetSize( [192,24] ); UI_ModelViewer_Resize(); UI_ModelViewer_ShowRenderer(); @@ -326,8 +340,8 @@ void UI_ModelViewer_Show ( void ) winViewer.Add( viewModel ); winViewer.Add( btnTabRenderer ); winViewer.Add( btnTabSequence ); - winViewer.Add( btnTabBody ); - winViewer.Add( btnTabTexture ); + //winViewer.Add( btnTabBody ); + //winViewer.Add( btnTabTexture ); winViewer.Add( chkBackground ); winViewer.Add( chkGround ); winViewer.Add( chkMirror ); diff --git a/src/menu-vgui/ui_musicplayer.qc b/src/menu-vgui/ui_musicplayer.qc old mode 100755 new mode 100644 index 2d949064..355a4bab --- a/src/menu-vgui/ui_musicplayer.qc +++ b/src/menu-vgui/ui_musicplayer.qc @@ -27,10 +27,10 @@ void UI_MusicPlayer_Show ( void ) static void MusicPlayer_Play ( void ) { string strSong; strSong = lsbSongs.GetItem( lsbSongs.GetSelected() ); - localcmd( sprintf( "music %s\n", substring( strSong, 11, strlen( strSong ) - 15 ) ) ); + localcmd( sprintf( "play %S\n", strSong ) ); } static void MusicPlayer_Stop ( void ) { - localcmd( "stopmusic\n" ); + localcmd( "stopsound\n" ); } static void MusicPlayer_ScrollUpdate ( void ) { scrlSong.SetValue( lsbSongs.GetOffset(), FALSE ); @@ -43,13 +43,13 @@ void UI_MusicPlayer_Show ( void ) g_iMusicPlayerInitialized = TRUE; winMusicPlayer = spawn( CUIWindow ); winMusicPlayer.SetTitle( "Music Player" ); - winMusicPlayer.SetSize( '256 180' ); - winMusicPlayer.SetIcon( "textures/ui/icons/cd" ); + winMusicPlayer.SetSize( [256,180] ); + winMusicPlayer.SetIcon( "gfx/icon16/ipod" ); - searchhandle shSongs = search_begin( "music/*.ogg", SEARCH_NAMESORT, TRUE ); + searchhandle shSongs = search_begin( "music/*.flac:music/*.wav:music/*.ogg:media/*.mp3:sound/music/*.mp3", SEARCH_NAMESORT | SEARCH_MULTISEARCH, TRUE ); lsbSongs = spawn( CUIList ); - lsbSongs.SetSize( '192 96' ); - lsbSongs.SetPos( '8 32 ' ); + lsbSongs.SetSize( [192, 96] ); + lsbSongs.SetPos( [8, 32] ); lsbSongs.SetItemCount( search_getsize( shSongs ) ); lsbSongs.CallOnScroll( MusicPlayer_ScrollUpdate ); @@ -59,7 +59,7 @@ void UI_MusicPlayer_Show ( void ) scrlSong = spawn( CUIScrollbar ); scrlSong.SetLength( 96 ); - scrlSong.SetPos( '201 32' ); + scrlSong.SetPos( [201,32] ); scrlSong.SetMin( 0 ); scrlSong.SetStep( 1 ); scrlSong.SetMax( lsbSongs.GetMaxVisibleItems() ); @@ -67,12 +67,16 @@ void UI_MusicPlayer_Show ( void ) btnPlay = spawn( CUIButton ); btnPlay.SetTitle( "Play" ); - btnPlay.SetPos( '8 132' ); + btnPlay.SetIcon( "gfx/icon16/control_play" ); + btnPlay.SetPos( [8,132] ); + btnPlay.SetSize([64,24]); btnPlay.SetFunc( MusicPlayer_Play ); btnStop = spawn( CUIButton ); btnStop.SetTitle( "Stop" ); - btnStop.SetPos( '96 132' ); + btnStop.SetIcon( "gfx/icon16/control_stop" ); + btnStop.SetPos( [96,132] ); + btnStop.SetSize([64,24]); btnStop.SetFunc( MusicPlayer_Stop ); g_uiDesktop.Add( winMusicPlayer ); diff --git a/src/menu-vgui/ui_newgame.qc b/src/menu-vgui/ui_newgame.qc old mode 100755 new mode 100644 index e66f71b5..72bd1c9f --- a/src/menu-vgui/ui_newgame.qc +++ b/src/menu-vgui/ui_newgame.qc @@ -27,7 +27,10 @@ void UI_NewGame_Show ( void ) static CUIRadio radHard; static void NewGame_Play ( void ) { - localcmd( "maxplayers 1\nmap measure\n" ); + if (radTraining.GetValue()) + localcmd( sprintf("maxplayers 1\ndeathmatch 0\ncoop 0\n%s", GameLibrary_GetInfo(GAMEINFO_TRAININGMAP)) ); + else + localcmd( sprintf("maxplayers 1\ndeathmatch 0\ncoop 0\n%s", GameLibrary_GetInfo(GAMEINFO_STARTMAP)) ); winNewGame.Hide(); } static void NewGame_Cancel ( void ) { @@ -45,7 +48,7 @@ void UI_NewGame_Show ( void ) winNewGame = spawn( CUIWindow ); winNewGame.SetTitle( "New Game" ); winNewGame.SetSize( '192 168' ); - winNewGame.SetIcon( "textures/ui/icons/desktop" ); + winNewGame.SetIcon( "gfx/icon16/new" ); g_uiDesktop.Add( winNewGame ); btnPlay = spawn( CUIButton ); diff --git a/src/menu-vgui/ui_quitgame.qc b/src/menu-vgui/ui_quitgame.qc old mode 100755 new mode 100644 index fc597ff1..34ce698b --- a/src/menu-vgui/ui_quitgame.qc +++ b/src/menu-vgui/ui_quitgame.qc @@ -35,7 +35,7 @@ void UI_QuitGame_Show ( void ) winQuitGame = spawn( CUIWindow ); winQuitGame.SetTitle( "Quit Game" ); winQuitGame.SetSize( '256 128' ); - winQuitGame.SetIcon( "textures/ui/icons/cancel" ); + winQuitGame.SetIcon( "gfx/icon16/stop" ); g_uiDesktop.Add( winQuitGame ); btnQuit = spawn( CUIButton ); @@ -52,6 +52,7 @@ void UI_QuitGame_Show ( void ) lblSure.SetTitle( "Do you wish to stop playing now?" ); lblSure.SetSize( '256 16' ); lblSure.SetPos( '0 48' ); + lblSure.SetAlignment(AF_NONE); btnQuit.SetFunc( QuitGame_Yes ); btnCancel.SetFunc( QuitGame_No ); diff --git a/src/platform/background.h b/src/platform/background.h new file mode 100644 index 00000000..8ec83273 --- /dev/null +++ b/src/platform/background.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2016-2024 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +void Background_Draw(vector atPos, vector withSize); diff --git a/src/platform/background.qc b/src/platform/background.qc new file mode 100755 index 00000000..2f6556d2 --- /dev/null +++ b/src/platform/background.qc @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2016-2024 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#define BACKGROUND_IMG "gfx/background" + +typedef enum +{ + BACK_AUTO = 0, + BACK_MATERIAL, + BACK_VGUI1, + BACK_WON +} bgMode_t; + +var bgMode_t g_bgMode; +var float autocvar_menu_forceBGMode = 0; + +typedef struct +{ + string strMat; + vector vecSize; + vector vecPos; +} backResource_t; + +backResource_t g_back800[] = +{ + {"resource/background/800_1_a_loading",[256,256,0],[0,0,0]}, + {"resource/background/800_1_b_loading",[256,256,0],[256,0,0]}, + {"resource/background/800_1_c_loading",[256,256,0],[512,0,0]}, + {"resource/background/800_1_d_loading",[32,256,0],[768,0,0]}, + {"resource/background/800_2_a_loading",[256,256,0],[0,256,0]}, + {"resource/background/800_2_b_loading",[256,256,0],[256,256,0]}, + {"resource/background/800_2_c_loading",[256,256,0],[512,256,0]}, + {"resource/background/800_2_d_loading",[32,256,0],[768,256,0]}, + {"resource/background/800_3_a_loading",[256,88,0],[0,512,0]}, + {"resource/background/800_3_b_loading",[256,88,0],[256,512,0]}, + {"resource/background/800_3_c_loading",[256,88,0],[512,512,0]}, + {"resource/background/800_3_d_loading",[32,88,0],[768,512,0]} +}; + +void +Background_RendererRestarted(void) +{ + if (fileExists("resource/background/800_1_a_loading.tga")) { + g_bgMode = BACK_VGUI1; + } else if (fileExists("gfx/shell/splash.bmp")) { + g_bgMode = BACK_WON; + } else { + g_bgMode = BACK_MATERIAL; + } + + /* issue `vid_reload` after changing this cvar */ + if (autocvar_menu_forceBGMode) { + g_bgMode = autocvar_menu_forceBGMode; + } + + if (g_bgMode == BACK_VGUI1) { + for (int i = 0; i < g_back800.length; i++) { + precache_pic(g_back800[i].strMat); + } + } else if (g_bgMode == BACK_WON) { + precache_pic("gfx/shell/splash.bmp"); + } else if (g_bgMode == BACK_MATERIAL) { + precache_pic(BACKGROUND_IMG); + } +} + +void +drawpic_flip(vector pos, string mat, vector size, vector color, float alpha) +{ + drawsubpic(pos, size, mat, [1,0], [-1,1], color, alpha, 0); +} + +void +Background_WON(vector vecPos, vector vecSize) +{ + drawpic(vecPos, "gfx/shell/splash.bmp", vecSize, [1,1,1], 1.0f); + /*drawpic_flip(vecPos + [vecSize[0], 0], "gfx/shell/splash.bmp", vecSize, [1,1,1] * 0.5f, 1.0f); + drawpic_flip(vecPos - [vecSize[0], 0], "gfx/shell/splash.bmp", vecSize, [1,1,1] * 0.5f, 1.0f);*/ +} + +void +Background_Steam(vector vecPos, vector vecSize) +{ + for (int i = 0; i < g_back800.length; i++) { + vector pos = [0.0f, 0.0f, 0.0f]; + vector size = [0.0f, 0.0f, 0.0f]; + + /* scale down 800x600 to 640x480 */ + float scaleX = vecSize[0] / 800; + float scaleY = vecSize[1] / 600; + size[0] = g_back800[i].vecSize[0] * scaleX; + size[1] = g_back800[i].vecSize[1] * scaleY; + pos[0] = (g_back800[i].vecPos[0] * scaleX); + pos[1] = (g_back800[i].vecPos[1] * scaleY); + + drawpic(vecPos + pos, \ + g_back800[i].strMat, \ + size, \ + [1,1,1], \ + 1.0f); + } +} + +void +Background_Draw2(vector vecPos, vector vecSize) +{ + switch (g_bgMode) { + case BACK_VGUI1: + Background_Steam(vecPos, vecSize); + break; + case BACK_WON: + Background_WON(vecPos, vecSize); + break; + case BACK_MATERIAL: + default: + drawpic(vecPos, BACKGROUND_IMG, vecSize, [ 1, 1, 1 ], 1.0f); + break; + } +} + +void +Background_Draw(vector vecPos, vector vecSize) +{ + /* when ingame, we'll draw a slight black tint... */ + if (clientstate() == 2) { + /* ...unless we're in background map mode. */ + if (!g_background) { + drawpic([0,0], "menutint", g_vidsize, [1,1,1], 1.0f); + } + } else { + /* clear screen */ + drawfill([0,0], g_vidsize, [0,0,0], 1.0f); + + Background_Draw2(vecPos, vecSize); + } +} diff --git a/src/platform/defs.h b/src/platform/defs.h index 71720159..fcf59ef7 100644 --- a/src/platform/defs.h +++ b/src/platform/defs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2022 Vera Visions LLC. + * Copyright (c) 2016-2024 Vera Visions LLC. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,9 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "init.h" #include "cmd.h" +#include "background.h" #include "util.h" #include "achievements.h" #include "activitypub.h" @@ -27,6 +29,7 @@ #include "gamelibrary.h" #include "maplibrary.h" #include "error.h" +#include "saves.h" /** Definitions for FTE's internal package manager. We don't want you to talk to this one directly within Nuclide. */ typedef enum diff --git a/src/platform/gamelibrary.qc b/src/platform/gamelibrary.qc index 7341e93b..a63a85ed 100644 --- a/src/platform/gamelibrary.qc +++ b/src/platform/gamelibrary.qc @@ -33,6 +33,10 @@ GameLibrary_IDForPackageName(string packageName) { string f; + if (!checkbuiltin(getpackagemanagerinfo)) { + return (-1i); + } + for (int i = 0; (getpackagemanagerinfo(i, GPMI_NAME)); i++) { string name; name = getpackagemanagerinfo(i, GPMI_NAME); @@ -444,6 +448,7 @@ GameLibrary_InitCustom(void) } /* count the package installed mods after */ + if (checkextension("getpackagemanagerinfo")) for (int i = 0; (getpackagemanagerinfo(i, GPMI_NAME)); i++) { string packageName = getpackagemanagerinfo(i, GPMI_NAME); string installStatus = getpackagemanagerinfo(i, GPMI_INSTALLED); @@ -496,6 +501,7 @@ GameLibrary_InitCustom(void) } /* iterate through all packages again */ + if (checkextension("getpackagemanagerinfo")) for (int i = 0i; (getpackagemanagerinfo(i, GPMI_NAME)); i++) { string packageName = getpackagemanagerinfo(i, GPMI_NAME); string installStatus = getpackagemanagerinfo(i, GPMI_INSTALLED); @@ -832,8 +838,8 @@ void GameLibrary_DebugList(void) { for (int i = 0; i < gameinfo_count; i++) { - print(sprintf("%i %s (%s)\n", i, games[i].game, games[i].gamedir)); + printf("%i %s (%s)\n", i, games[i].game, games[i].gamedir); } - print(sprintf("\t%i game(s) loaded.", gameinfo_count)); + printf("\t%i game(s) loaded.\n", gameinfo_count); } diff --git a/src/platform/includes.src b/src/platform/includes.src index a5f30b0d..efb14ade 100644 --- a/src/platform/includes.src +++ b/src/platform/includes.src @@ -1,5 +1,6 @@ #includelist achievements.qc +background.qc master.qc modserver.qc music.qc @@ -10,5 +11,7 @@ updates.qc gamelibrary.qc maplibrary.qc activitypub.qc +saves.qc cmd.qc +init.qc #endlist diff --git a/src/server/mapC_math.h b/src/platform/init.h similarity index 86% rename from src/server/mapC_math.h rename to src/platform/init.h index af1dabad..1ceddba5 100644 --- a/src/server/mapC_math.h +++ b/src/platform/init.h @@ -14,8 +14,5 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/*! @file mapC_math.h - @brief Server-side plugin wrappers for math related functions. -*/ - -#include "../shared/math.h" \ No newline at end of file +void Platform_Init(void); +void Platform_RendererRestarted(void); diff --git a/src/platform/init.qc b/src/platform/init.qc new file mode 100644 index 00000000..62434561 --- /dev/null +++ b/src/platform/init.qc @@ -0,0 +1,15 @@ +void +Platform_Init(void) +{ + Platform_RegisterCommands(); + GameLibrary_Init(); + MapLibrary_Init(); + Saves_Init(); + Platform_RendererRestarted(); +} + +void +Platform_RendererRestarted(void) +{ + Background_RendererRestarted(); +} diff --git a/src/platform/maplibrary.qc b/src/platform/maplibrary.qc index 4d8e92b9..7716c109 100644 --- a/src/platform/maplibrary.qc +++ b/src/platform/maplibrary.qc @@ -36,6 +36,8 @@ MapLibrary_MapInGameDir(string fileName, string gameDir) { bool list = true; + //printf("Checking %S %S...\n", fileName, gameDir); + /* only look for maps in the current gamedir, requires SEARCH_FULLPACKAGE */ if (gameDir != MapLibrary_GetMapGamedir()) { return false; @@ -122,7 +124,7 @@ MapLibrary_Init(void) } /* search for all maps in the current PATH */ - mapsearch = search_begin("maps/*.bsp", SEARCH_NAMESORT | SEARCH_FULLPACKAGE, TRUE); + mapsearch = search_begin("maps/*.bsp:maps/*/*.bsp", SEARCH_NAMESORT | SEARCH_FULLPACKAGE | SEARCH_MULTISEARCH, TRUE); mapCount = search_getsize(mapsearch); /* we now iterate over the search entries to filter results out */ @@ -142,7 +144,7 @@ MapLibrary_Init(void) g_mapLibrary = (mapLibrary_t *)memalloc(sizeof(mapLibrary_t) * g_mapLibrary_count); /* let's do it again, but this time we'll sort the data into our array */ - mapsearch = search_begin("maps/*.bsp", SEARCH_NAMESORT | SEARCH_FULLPACKAGE, TRUE); + mapsearch = search_begin("maps/*.bsp:maps/*/*.bsp", SEARCH_NAMESORT | SEARCH_FULLPACKAGE | SEARCH_MULTISEARCH, TRUE); mapCount = search_getsize(mapsearch); for (i = 0i; i < mapCount; i++) { @@ -197,4 +199,4 @@ MapLibrary_GetInfo(int mapID, mapType_t infoType) default: return __NULL__; } -} \ No newline at end of file +} diff --git a/src/platform/saves.h b/src/platform/saves.h new file mode 100644 index 00000000..17c4f404 --- /dev/null +++ b/src/platform/saves.h @@ -0,0 +1,23 @@ + +typedef struct +{ + string m_strName; + string m_strPic; +} savegame_t; +var savegame_t *g_savegames; +var int g_savegame_count; + +/** Options querying Map Library entries using `MapLibrary_GetInfo()`. */ +typedef enum +{ + SAVEINFO_NAME, /**< (string) Name of the save. E.g. quick */ + SAVEINFO_PREVIEW /**< (string) URL to a preview of the save. __NULL__ if not available.*/ +} saveInfo_t; + +/** Returns the total amount of savegames available. */ +int Saves_GetSaveCount(void); + +/** Retrieve information about a given saveID. See saveInfo_t for which fields you can query. */ +__variant Saves_GetInfo(int, saveInfo_t); + +void Saves_Init(void); diff --git a/src/platform/saves.qc b/src/platform/saves.qc new file mode 100644 index 00000000..da66396c --- /dev/null +++ b/src/platform/saves.qc @@ -0,0 +1,44 @@ +void +Saves_Init(void) +{ + searchhandle searchy; + searchy = search_begin("saves/*/info.fsv", SEARCH_NAMESORT, TRUE); + + g_savegame_count = search_getsize(searchy); + g_savegames = memalloc(sizeof(savegame_t) * g_savegame_count); + + for (int i = 0; i < g_savegame_count; i++) { + string fullpath = search_getfilename(searchy, i); + g_savegames[i].m_strName = substring(fullpath, 6, strlen(fullpath) - 15); + g_savegames[i].m_strPic = sprintf("saves/%s/screeny.tga", g_savegames[i].m_strName ); + precache_pic(g_savegames[i].m_strPic); + } + + search_end(searchy); +} + +int +Saves_GetSaveCount(void) +{ + return (g_savegame_count); +} + +__variant +Saves_GetInfo(int saveID, saveInfo_t saveInfo) +{ + if (saveID >= g_savegame_count || saveID < 0i) { + NSError("Invalid save id %i", saveID); + return __NULL__; + } + + switch (saveInfo) { + case SAVEINFO_NAME: + return g_savegames[saveID].m_strName; + break; + case SAVEINFO_PREVIEW: + return g_savegames[saveID].m_strPic; + break; + default: + return __NULL__; + } +} diff --git a/src/platform/servers.h b/src/platform/servers.h new file mode 100644 index 00000000..a76437cc --- /dev/null +++ b/src/platform/servers.h @@ -0,0 +1,15 @@ +/** Options for querying Game Library entry information using `GameLibrary_GetInfo()` */ +typedef enum +{ + SERVERGAME_TITLE, /**< (string) The title of the game. E.g. "Action Game" */ + SERVERGAME_ADDRESS, /**< (string) The game directory name. E.g. "data" */ + SERVERGAME_PING, /**< (int) The directory to be loaded before the game directory. */ + SERVERGAME_PLAYERS, /**< (int) The first game directory to be loaded. */ + SERVERGAME_MAXPLAYERS, /**< (int) The game its official website. */ + SERVERGAME_MAP, /**< (string) Version number string. */ + SERVERGAME_GAME, /**< (string) The size of the game, in bytes. */ +} serverGame_t; + + +/** Retrieves fields for a given game. See gameInfo_t for a list of fields you can query. */ +__variant Servers_GetInfo(int, serverGame_t); diff --git a/src/platform/servers.qc b/src/platform/servers.qc new file mode 100644 index 00000000..2c717825 --- /dev/null +++ b/src/platform/servers.qc @@ -0,0 +1,35 @@ + +__variant +Servers_GetInfo(int serverID, serverGame_t infoType) +{ + if (serverID >= Master_GetTotalServers() || serverID < 0i) { + NSError("Invalid server id %i.", serverID); + return __NULL__; + } + + switch (infoType) { + case SERVERGAME_TITLE: + return (string)gethostcachestring(srv_fldName, i) + break; + case SERVERGAME_ADDRESS: + return (string)gethostcachestring(srv_fldAdress, i) + break; + case SERVERGAME_PING: + return (string)gethostcachestring(srv_fldPing, i) + break; + case SERVERGAME_PLAYERS: + return (string)gethostcachestring(srv_fldPlayers, i) + break; + case SERVERGAME_MAXPLAYERS: + return (string)gethostcachestring(srv_fldMaxplayers, i) + break; + case SERVERGAME_MAP: + return (string)gethostcachestring(srv_fldMap, i) + break; + case SERVERGAME_GAME: + return (string)gethostcachestring(srv_fldGame, i) + break; + default: + return __NULL__; + } +} diff --git a/src/server/NSGameRules.h b/src/server/NSGameRules.h index fbdb6d1c..ac4d7bd6 100644 --- a/src/server/NSGameRules.h +++ b/src/server/NSGameRules.h @@ -32,6 +32,7 @@ public: virtual void Save(float); virtual void Restore(string,string); virtual void RestoreComplete(void); + virtual void Input(entity, string, string); /** Overridable: Called when all map entities have initialized. */ virtual void InitPostEnts(void); @@ -71,6 +72,10 @@ public: In a singleplayer game, it might load the most recent save. @return True/false depending on the respawn succeeded. */ virtual bool PlayerRequestRespawn(NSClientPlayer); + + /** Overridable: called when a NSClientPlayer requests joining a specific team. + @return True/false depending on the team change success. */ + virtual bool PlayerRequestTeam(NSClientPlayer, int team); /* level transitions */ /** Overridable: Called to set up new level parms for any NSClientPlayer. */ @@ -107,6 +112,7 @@ public: /** Returns if the gamerule is a multiplayer game. */ virtual bool IsMultiplayer(void); + /* chat related methods */ /** Called by Nuclide when the server has received a chat message that is to be distributed amongst all clients, regardless of team. */ diff --git a/src/server/NSGameRules.qc b/src/server/NSGameRules.qc index a70dbc55..182db65e 100644 --- a/src/server/NSGameRules.qc +++ b/src/server/NSGameRules.qc @@ -22,6 +22,9 @@ void NSGameRules::NSGameRules(void) { forceinfokey(world, "teamplay", "0"); + forceinfokey(world, sprintf("teamspawn_%d", TEAM_CONNECTING), ""); + forceinfokey(world, sprintf("teamspawn_%d", TEAM_UNASSIGNED), "info_player_start"); + forceinfokey(world, sprintf("teamspawn_%d", TEAM_SPECTATOR), "info_spectator_start"); identity = 2; } @@ -49,6 +52,12 @@ NSGameRules::Restore(string strKey, string strValue) } } +void +NSGameRules::Input(entity eAct, string strInput, string strData) +{ + RuleC_CallInput(m_ruleProgs, eAct, strInput, strData); +} + void NSGameRules::RestoreComplete(void) { @@ -68,6 +77,13 @@ void NSGameRules::FrameStart(void) { //print("StartFrame!\n"); + + /* hack */ + if (time < 2.5f) { + return; + } + + RuleC_CallFrame(m_ruleProgs, "CodeCallback_FrameStart"); } bool NSGameRules::ConsoleCommand(NSClientPlayer pl, string cmd) @@ -202,6 +218,10 @@ NSGameRules::SpectatorThink(NSClientSpectator pl) int NSGameRules::MaxItemPerSlot(int slot) { + if (m_ruleProgs) { + return RuleC_CallMaxItemsPerSlot(m_ruleProgs, slot, "CodeCallback_MaxItemPerSlot"); + } + return (-1); } @@ -368,6 +388,12 @@ NSGameRules::PlayerRequestRespawn(NSClientPlayer pl) return RuleC_CallRequestSpawn(m_ruleProgs, pl, "CodeCallback_PlayerRequestRespawn"); } +bool +NSGameRules::PlayerRequestTeam(NSClientPlayer pl, int teamNum) +{ + return RuleC_CallRequestTeam(m_ruleProgs, pl, teamNum, "CodeCallback_CallRequestTeam"); +} + void NSGameRules::ChatMessageAll(NSClient cl, string strMessage) { @@ -442,7 +468,7 @@ NSGameRules::InitFromProgs(string pathToProgs) if (mainFunction) { externset(newRule.m_ruleProgs, this, "self"); - thread(mainFunction()); + thread(mainFunction()) } else { NSError("%S does not have a main function.", pathToProgs); } @@ -450,15 +476,3 @@ NSGameRules::InitFromProgs(string pathToProgs) return (newRule); } - -void -setServerInfo(string serverKey, string setValue) -{ - forceinfokey(world, serverKey, setValue); -} - -string -getServerInfo(string serverKey) -{ - return infokey(world, serverKey); -} diff --git a/src/server/api.h b/src/server/api.h new file mode 100644 index 00000000..51730300 --- /dev/null +++ b/src/server/api.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#pragma target fte_5768 +#define QWSSQC + +#include "../shared/fteextensions.qc" +#include "../shared/global.h" +#include "../shared/math.h" +#include "api_func.h" +#include "../shared/api.h" + +void +main(void) +{ + _server_main(); + _shared_main(); +} diff --git a/src/server/api.qc b/src/server/api.qc new file mode 100644 index 00000000..87d33a10 --- /dev/null +++ b/src/server/api.qc @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2016-2024 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +void +SVPF_game_LoadNextMap(void) +{ + localcmd("nextmap\n"); +} + +void +SVPF_game_CleanUpMap(void) +{ + //localcmd("respawnEntities\n"); + + /* user created decals (not sprays) */ + for (entity eFind = world; (eFind = find(eFind, ::classname, "tempdecal"));) { + //ents.Input(eFind, "Destroy", "", world); + } + + /* respawn all entities. */ + for (entity a = world; (a = findfloat(a, ::identity, 1));) { + NSEntity caw = (NSEntity)a; + if (caw.classname != "player") + caw.Respawn(); + } + + /* clear the corpses/items, you name it*/ + for (entity eFind = world; (eFind = find(eFind, ::classname, "remove_me"));) { + if (eFind.identity) { + NSEntity toRemove = (NSEntity)eFind; + toRemove.Destroy(); + } else { + remove(eFind); + } + } + + WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); + WriteByte(MSG_MULTICAST, EV_CLEARDECALS); + msg_entity = world; + multicast([0,0,0], MULTICAST_ALL); +} + +string +SVPF_game_GetMap(void) +{ + return (mapname); +} + +string +SVPF_game_GetNextMap(void) +{ + return ""; +} + +void +SVPF_game_TeleportToSpawn(entity targetClient) +{ + Spawn_TeleportToSpawn(targetClient); +} + +void +SVPF_game_SetSpawnPoint(string spawnPoint) +{ + forceinfokey(world, sprintf("teamspawn_%d", TEAM_UNASSIGNED), spawnPoint); +} + +int +SVPF_actor_GetReserveAmmo(NSActor targetActor, int ammoID) +{ + if (!targetActor) { + return (0i); + } + + return targetActor.GetReserveAmmo(ammoID); +} + +bool +SVPF_actor_MaxAmmo(NSActor targetActor, int ammoID) +{ + /* deny anything funny */ + if (!targetActor) { + return (true); + } + + return targetActor.MaxAmmo(ammoID); +} + +string +SVPF_actor_GetInventory(NSActor targetActor) +{ + string outputString = ""; + NSItem m_listStart = targetActor.m_itemList; + + while (m_listStart) { + outputString = strcat(outputString, m_listStart.classname, " "); + m_listStart = m_listStart.m_nextItem; + } + + return (outputString); +} + +string +SVPF_util_TimeToString(int realTime, int zoneType, string formatString) +{ + /* supposed to take extra (optional parameters...) */ + if (zoneType == 1i) { + return strftime(true, formatString); + } else { + return strftime(true, formatString); + } +} + +bool +SVPF_exists_InPVS(entity testEntity, vector testCoord) +{ + return checkpvs(testCoord, testEntity); +} + +bool +SVPF_exists_InMap(string className) +{ + return find(world, ::classname, className) ? (true) : (false); +} + +bool +SVPF_exists_InVFS(string fileName) +{ + return fileExists(fileName); +} + +/* damage/combat */ +/* helper functions */ + +void +SVPF_combat_Damage(entity targetEnt, entity inflictingEnt, entity attackingEnt, string damageDef, vector damageOrigin, vector damageDir, vector hitLocation) +{ + NSSurfacePropEntity theTarget; + + /* common filters */ + if (targetEnt.takedamage == DAMAGE_NO) { + return; + } + + if (isGodMode(targetEnt) == true) { + return; + } + + theTarget = (NSSurfacePropEntity)targetEnt; + + /* don't use IsAlive(), else we can't gib */ + if (!theTarget.GetHealth()) { + return; + } + + NSDict findDecl = (NSDict)find(world, ::declclass, damageDef); + + if (findDecl) { + theTarget.Damage(inflictingEnt, attackingEnt, findDecl, 1.0, damageDir, hitLocation); + return; + } + + NSError("Cannot find decl %S for damage info.", damageDef); +} + +void +SVPF_combat_RadiusDamage(vector damageCenter, float damageRange, int damageMin, int damageMax, entity attackingEnt, string strDamageDecl) +{ + vector entPos = g_vec_null; + float entDistance = 0.0f; + int newDamage = 0i; + float damageFrac = 0.0f; + vector dmgDir = g_vec_null; + + for (NSSurfacePropEntity e = __NULL__; (e = (NSSurfacePropEntity)nextent(e));) { + if (e.takedamage == DAMAGE_NO) { + continue; + } + + entPos = e.WorldSpaceCenter(); + + /* don't bother if it's not anywhere near us */ + entDistance = length(damageCenter - entPos); + + if (entDistance > damageRange) { + continue; + } + + /* can we physically hit this thing? */ + if (damageMax > 0i) { + if (e.CanBeDamaged(damageCenter, entPos) == false) { + continue; + } + } + + /* calculate new damage values */ + damageFrac = (damageRange - entDistance) / damageRange; + newDamage = (int)lerp(fabs((float)damageMin), (float)damageMax, damageFrac); + dmgDir = dirFromTarget(damageCenter, entPos); + + if (e == attackingEnt) { + newDamage *= 0.5f; + } + + NSDict damageDecl; + + if (STRING_SET(strDamageDecl)) { + int declID = EntityDef_IDFromName(strDamageDecl); + damageDecl = NSDict::InitWithSpawnData(EntityDef_GetSpawnData(declID)); + } else { + damageDecl = spawn(NSDict); + } + + + damageDecl.AddKey("damage", itos(newDamage)); + e.Damage(attackingEnt, attackingEnt, damageDecl, 1.0, dmgDir, trace_endpos); + remove(damageDecl); + } +} + +void +SVPF_combat_Obituary(string targetName, string attackerName, string weaponDef, string meansOfDeath) +{ + obituary(targetName, attackerName, weaponDef, meansOfDeath); +} diff --git a/src/server/api_func.h b/src/server/api_func.h new file mode 100644 index 00000000..2a77c74e --- /dev/null +++ b/src/server/api_func.h @@ -0,0 +1,218 @@ +.float deaths; + +/** @defgroup serverAPI Server-side multiprogs API + @brief Server-side multiprogs API + @ingroup multiprogs + @ingroup server + +APIs used by MapC progs, game rules and the server progs exclusively. + +![Package](package_add.png) + +@{ +*/ + +/* Util library */ +typedef struct +{ + /** Returns the current time. + + @param realTime specifies the time in seconds since 01/01/1970. + @param zoneType specifies the time zone to use. 0 = UTC, 1 = Local. + @param formatString is a C-language, strftime styled string setting the output format + @return Euler-angles generated from the input. */ + string TimeToString(int realTime, int zoneType, string formatString); +} utilAPI_t; +var utilAPI_t util; + +/* Exists library */ +typedef struct +{ + bool InMap(string); + bool InPVS(entity, vector); + bool InVFS(string fileName); +} existsAPI_t; +var existsAPI_t exists; + +/* Ents library */ +typedef struct +{ + /** Creates a new entity of a given class name. + It is guaranteed to return an entity, unless you + have run out of memory. + + @param className the type of entity class to create. + @param spawnPos the position at which it should spawn. + @return The created entity. */ + entity Create(string className, vector spawnPos); + /** Precaches a given entity class. + Ensuring models, sounds and other assets referenced + within are loaded ahead of time. + + @param className to precache + @return Success. */ + bool Precache(string className); + /** Transitions an entity from one class to another. + + @param targetEntity is the target entity. + @param className is the class type to change targetEntity to. + @return The created entity. */ + entity ChangeToClass(entity targetEntity, string className); + /** Sends an input (See NSIO::Input) to an entity. + + While you're able to manipulate entities in most ways using bare MapC, you might want to change Nuclide specific attributes of them as well. This can only be done using the I/O system. + + For the variety of inputs an entity supports, please look at the respective entity-specific documentation. + + @param target is the entity which will receive the input + @param inputName is the name of the input. E.g. "SetOrigin" + @param dataString contains parameters for the input. E.g. "0 0 0" + @param activator references which entity is "responsible" for triggering this input. */ + entity Input(entity target, string inputName, string dataString, entity activator); + /** Returns true/false depending on if the entity is an AI character. + + @param entityToCheck specifies the entity to check.*/ + bool isAI(entity entityToCheck); + /** Returns true/false depending on if the entity is alive. + + @param entityToCheck specifies the entity to check.*/ + bool isAlive(entity entityToCheck); + /** Returns true/false depending on if the entity is in "god" mode. + + @param entityToCheck specifies the entity to check.*/ + bool isGodMode(entity entityToCheck); + /** Returns true/false depending on if the entity is a player. + + @param entityToCheck specifies the entity to check.*/ + bool isPlayer(entity entityToCheck); + /** Returns true/false depending on if the entity is either a player, or AI character. + + @param entityToCheck specifies the entity to check.*/ + bool isSentient(entity entityToCheck); + /** Returns true/false depending on if the entity is a bot. + + @param entityToCheck specifies the entity to check.*/ + bool isBot(entity entityToCheck); +} entsAPI_t; +var entsAPI_t ents; + +/* Game library */ +typedef struct +{ + void LoadNextMap(void); + void CleanUpMap(void); + string GetMap(void); + string GetNextMap(void); + void SetSpawnPoint(string); + void TeleportToSpawn(entity); +} gameAPI_t; +var gameAPI_t game; + +/* MOTD library */ +typedef struct +{ + void LoadDefault(void); + void LoadFromFile(string); +} motdAPI_t; +var motdAPI_t motd; + +/* MOTD library */ +typedef struct +{ + string GetInventory(entity); + int GetReserveAmmo(entity, int); + bool MaxAmmo(entity, int); +} actorAPI_t; +var actorAPI_t actor; + +typedef struct +{ + /** Applies damage to a given entity. + Requires the use of damageDef/entityDef since we're run out of parameters in QuakeC. + + @param targetEnt is the entity receiving the damage. + @param inflictingEnt is the entity causing the damage (e.g. a projectile, rocket) + @param attackingEnt is the entity owning up to the damage. + @param damageDef is the damageDef containing all the info, including damage points + @param damageOrigin is the location where the damage comes from. + @param damageDir is the direction the damage is coming from. + @param hitLocation is the final hit location, where the damage is applied. */ + void Damage(entity targetEnt, entity inflictingEnt, entity attackingEnt, string damageDef, vector damageOrigin, vector damageDir, vector hitLocation); + /** Does damage to all entities within a specified radius with a linear falloff. + If a negative damageMax value is supplied, then no collision checks will be performed. + So radiusDamage calls will not be obstructed by level or entity geometry. + + @param damageCenter is the location of the center, at which the wave originates. + @param damageRange is the radius (in game units) of the wave. + @param damageMax is the maximum damage that can be done by this wave. + @param damageMin is the minimum amount of damage done, at the very edge. + @param attackingEnt is the entity owning up to the damage. + @param attackingEnt is the entity owning up to the damage. */ + void RadiusDamage(vector damageCenter, float damageRange, int damageMin, int damageMax, entity attackingEnt, string damageDef); + /** Lets everyone in the game know that something, or something, has passed. + + @param targetName is the entity that has passed away. + @param attackerName is responsible. Can be empty. + @param weaponDef is the weapon used. Can be empty. + @param meansOfDeath is the additional means. Could mean something extra. */ + void Obituary(string targetName, string attackerName, string weaponDef, string meansOfDeath); +} combatAPI_t; +var combatAPI_t combat; + +/** @} */ // end of multiprogs + +__variant +linkToServerProgs(string funcName) +{ + static void empty(void) + { + print("Called unimplemented server-side API call.\n"); + breakpoint(); + } + + void *func = externvalue(0, funcName); + + if (func) { + return ((__variant)func); + } else { + return (empty); + } +} + +void +_server_main(void) +{ + game.LoadNextMap = linkToServerProgs("SVPF_game_LoadNextMap"); + game.CleanUpMap = linkToServerProgs("SVPF_game_CleanUpMap"); + game.GetMap = linkToServerProgs("SVPF_game_GetMap"); + game.GetNextMap = linkToServerProgs("SVPF_game_GetNextMap"); + game.SetSpawnPoint = linkToServerProgs("SVPF_game_SetSpawnPoint"); + game.TeleportToSpawn = linkToServerProgs("SVPF_game_TeleportToSpawn"); + + combat.Damage = linkToServerProgs("SVPF_combat_Damage"); + combat.RadiusDamage = linkToServerProgs("SVPF_combat_RadiusDamage"); + combat.Obituary = linkToServerProgs("SVPF_combat_Obituary"); + + ents.Create = linkToServerProgs("spawnClass"); + ents.ChangeToClass = linkToServerProgs("changeClass"); + ents.Precache = linkToServerProgs("EntityDef_Precache"); + ents.Input = linkToServerProgs("sendInput"); + ents.isAI = linkToServerProgs("isAI"); + ents.isAlive = linkToServerProgs("isAlive"); + ents.isGodMode = linkToServerProgs("isGodMode"); + ents.isPlayer = linkToServerProgs("isPlayer"); + ents.isSentient = linkToServerProgs("isSentient"); + + actor.GetInventory = linkToServerProgs("SVPF_actor_GetInventory"); + actor.GetReserveAmmo = linkToServerProgs("SVPF_actor_GetReserveAmmo"); + actor.MaxAmmo = linkToServerProgs("SVPF_actor_MaxAmmo"); + + exists.InMap = linkToServerProgs("SVPF_exists_InMap"); + exists.InVFS = linkToServerProgs("SVPF_exists_InVFS"); + exists.InPVS = linkToServerProgs("SVPF_exists_InPVS"); + + motd.LoadDefault = linkToServerProgs("MOTD_LoadDefault"); + motd.LoadFromFile = linkToServerProgs("MOTD_LoadFromFile"); + + util.TimeToString = linkToServerProgs("SVPF_util_TimeToString"); +} diff --git a/src/server/cmd_cl.qc b/src/server/cmd_cl.qc index 43b4421b..13646bc9 100644 --- a/src/server/cmd_cl.qc +++ b/src/server/cmd_cl.qc @@ -29,7 +29,7 @@ Cmd_ParseClientCommand(NSClient sender, string cmd, int commandArguments) if (commandArguments == 2) { g_grMode.ChatMessageTeam(sender, argv(1)); } else { - g_grMode.ChatMessageTeam(sender, substring(cmd, 10, -2)); + g_grMode.ChatMessageTeam(sender, substring(cmd, 9, -1)); } break; case "spectate": @@ -78,7 +78,10 @@ Cmd_ParseClientCommand(NSClient sender, string cmd, int commandArguments) case "listAmmo": Ammo_DebugList(); break; + case "joinTeam": + g_grMode.PlayerRequestTeam((NSClientPlayer)sender, (int)stoi(argv(1))); + break; default: clientcommand(sender, cmd); } -} \ No newline at end of file +} diff --git a/src/server/cmd_sv.qc b/src/server/cmd_sv.qc index f51f3ef3..bdff96c5 100644 --- a/src/server/cmd_sv.qc +++ b/src/server/cmd_sv.qc @@ -112,7 +112,7 @@ CMD_Input(void) if (inputTarget) { inputTarget.Input(self, inputName, inputData); - print(sprintf("Sending input to %d, %S: %S\n", entNum, inputName, inputData)); + printf("Sending input to %d, %S: %S\n", entNum, inputName, inputData); } } @@ -121,7 +121,7 @@ CMD_ListTargets(void) { for (entity a = world; (a = findfloat(a, ::identity, 1));) { if (a.targetname) { - print(sprintf("%d: %s (%s)\n", num_for_edict(a), a.targetname, a.classname)); + printf("%d: %s (%s)\n", num_for_edict(a), a.targetname, a.classname); } } } @@ -181,6 +181,23 @@ CMD_Spawn(void) setorigin(unit, trace_endpos); } +static void +CMD_PropSpawn(void) +{ + string newModel = argv(1); + makevectors(self.v_angle); + traceline(self.origin, self.origin + (v_forward * 1024), MOVE_NORMAL, self); + + prop_physics newProp = spawn(prop_physics); + newProp.SetModel(newModel); + newProp.SetOriginUnstick(trace_endpos + [0,0,32]); + newProp.Spawn(); + newProp.SetModel(newModel); + newProp.SetOriginUnstick(trace_endpos + [0,0,32]); + newProp.ClearVelocity(); + newProp.Wake(); +} + bool Cmd_ParseServerCommand(void) { @@ -227,6 +244,9 @@ Cmd_ParseServerCommand(void) case "spawnDef": CMD_Spawn(); break; + case "propSpawn": + CMD_PropSpawn(); + break; #ifdef BOT_INCLUDED case "way": NodeEdit_Cmd(); @@ -245,4 +265,4 @@ Cmd_ParseServerCommand(void) return (false); } return (true); -} \ No newline at end of file +} diff --git a/src/server/defs.h b/src/server/defs.h index 2df9d398..8411c938 100644 --- a/src/server/defs.h +++ b/src/server/defs.h @@ -14,6 +14,8 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "api_func.h" +#include "../shared/api.h" #include "../shared/entityDef.h" #include "NSOutput.h" #include "NSGameRules.h" @@ -127,7 +129,6 @@ NSEntity g_dmg_eTarget; int g_dmg_iDamage; bodyType_t g_dmg_iHitBody; int g_dmg_iFlags; -int g_dmg_iWeapon; vector g_dmg_vecLocation; var bool g_ents_initialized = FALSE; diff --git a/src/server/entry.qc b/src/server/entry.qc index f06f8616..e3874c42 100644 --- a/src/server/entry.qc +++ b/src/server/entry.qc @@ -43,13 +43,15 @@ The `self` global is the connecting client in question. void ClientConnect(void) { + EntityDef_SpawnClassname("player"); self.gotData = false; /* don't carry over team settings from a previous session */ - forceinfokey(self, "*team", "0"); + self.team = TEAM_CONNECTING; + self.flags |= FL_CLIENT; + userinfo.SetString(self, "*team", "0"); if (g_ents_initialized) { - Entity_CreateClass("player"); g_grMode.PlayerConnect((NSClientPlayer)self); } } @@ -61,8 +63,9 @@ This means the fields will still be accessible inside of this function. void ClientDisconnect(void) { - if (g_ents_initialized) + if (g_ents_initialized) { g_grMode.PlayerDisconnect((NSClientPlayer)self); + } /* this will hide/remove the player from other clients */ NSClientPlayer pl = (NSClientPlayer)self; @@ -86,8 +89,9 @@ The `self` global is the client issuing the command. void ClientKill(void) { - if (g_ents_initialized) + if (g_ents_initialized) { g_grMode.PlayerKill((NSClientPlayer)self); + } } /** This is run every frame on every spectator. @@ -110,7 +114,7 @@ The `self` global is the connecting NSClientSpectator in question. void SpectatorConnect(void) { - spawnfunc_NSClientSpectator(); + ents.ChangeToClass(self, "spectator"); } /** Called when a NSClientSpectator leaves the server. @@ -131,12 +135,15 @@ past levels for the player in question. void PutClientInServer(void) { - if (g_ents_initialized) + /* we're officially in-game now. */ + self.team = TEAM_UNASSIGNED; + + if (g_ents_initialized) { g_grMode.PlayerSpawn((NSClientPlayer)self); + } /* handle transitions */ if (fileExists("data/trans.dat")) { - for (entity a = world; (a = findfloat(a, ::identity, 1));) { NSEntity levelEnt = (NSEntity)a; levelEnt.TransitionComplete(); @@ -155,8 +162,9 @@ PutClientInServer(void) for (entity a = world; (a = find(a, ::targetname, "game_playerspawn"));) { NSEntity t = (NSEntity)a; - if (t.Trigger) + if (t.Trigger) { t.Trigger(self, TRIG_TOGGLE); + } } /* the game and its triggers start when the player is ready to see it */ @@ -191,8 +199,9 @@ PlayerPreThink(void) } #endif - if (g_ents_initialized) + if (g_ents_initialized) { g_grMode.PlayerPreFrame((NSClientPlayer)self); + } } /** Run after game physics have taken place. @@ -221,7 +230,7 @@ PlayerPostThink(void) NSClientPlayer pl = (NSClientPlayer)self; g_grMode.PlayerPostFrame((NSClientPlayer)self); pl.EvaluateEntity(); - forceinfokey(pl, "*score", ftos(pl.score)); + userinfo.SetString(pl, "*score", ftos(pl.score)); } } @@ -286,6 +295,8 @@ SV_RunClientCommand(void) BreakModel_SendClientData(self); self.gotData = true; } + + self.impulse = 0; } /** Any 'cmd' from the client get sent here and handled. @@ -320,13 +331,16 @@ init(float prevprogs) NSLog("Built: %s %s", __DATE__, __TIME__); NSLog("QCC: %s", __QCCVER__); + _server_main(); + _shared_main(); + Skill_Init(); EntityDef_Init(); Ammo_Init(); MapTweaks_Init(); MapC_Init(); - Plugin_Init(); + Plugin_Init(); Constants_Init(); Sound_Init(); PropData_Init(); @@ -334,7 +348,7 @@ init(float prevprogs) DecalGroups_Init(); /* DO NOT EVER CHANGE THESE. */ - cvar_set("r_meshpitch", "1"); + cvars.SetString("r_meshpitch", "1"); /* ENGINE, PLS FIX */ input_cursor_entitynumber = 0; @@ -346,20 +360,21 @@ method called at the beginning of them having spawned. void init_respawn(void) { - int endspawn = 0; + int spawnCounter = 0i; - if (g_ents_initialized) + if (g_ents_initialized) { g_grMode.InitPostEnts(); + } /* of all the map entities that we wanted to spawn, how many are left? */ for (entity a = world; (a = findfloat(a, ::_mapspawned, true));) { - endspawn++; + NSEntity ent = (NSEntity)a; + ent.Respawn(); + spawnCounter++; } - NSLog("...%i entities spawned (%i inhibited)", g_ent_spawned, g_ent_spawned - endspawn); - + NSLog("...%i entities spawned (%i inhibited)", g_ent_spawned, g_ent_spawned - spawnCounter); Nodes_Init(); - remove(self); } @@ -376,8 +391,6 @@ initents(void) MOTD_Init(); PMove_Init(); - /** compat... */ - Sound_Precache("Player.GaspLight"); Sound_Precache("Player.GaspHeavy"); Sound_Precache("Player.WaterEnter"); @@ -398,7 +411,7 @@ initents(void) if (!g_grMode) { Game_InitRules(); - forceinfokey(world, "mode", g_grMode.Title()); + serverinfo.SetString("mode", g_grMode.Title()); } Game_Worldspawn(); @@ -412,16 +425,17 @@ initents(void) g_respawntimer.nextthink = time + 0.1f; /* menu background lock */ - if (cvar("sv_background") == 1) { - forceinfokey(world, "background", "1"); + if (cvars.GetBool("sv_background") == true) { + /* trade them in. */ + serverinfo.SetBool("background", true); localcmd("sv_background 0\n"); } else { - forceinfokey(world, "background", "0"); + serverinfo.SetBool("background", false); } /* the maxclients serverinfo key? yeah, that one lies to the client. so * let's add our own that we can actually trust. */ - forceinfokey(world, "sv_playerslots", cvar_string("sv_playerslots")); + serverinfo.SetInteger("sv_playerslots", cvars.GetInteger("sv_playerslots")); MapC_CallMainFunction(); Plugin_InitEnts(); @@ -432,10 +446,10 @@ initents(void) g_ents_initialized = TRUE; /* engine hacks for dedicated servers */ - cvar_set("s_nominaldistance", "1536"); + cvars.SetFloat("s_nominaldistance", 1536); /* other engine hacks */ - cvar_set("sv_nqplayerphysics", "0"); + cvars.SetBool("sv_nqplayerphysics", false); #ifdef BOT_INCLUDED BotLib_Init(); @@ -471,9 +485,11 @@ ConsoleCmd(string cmd) pl = (NSClientPlayer)self; /* give the game-mode a chance to override us */ - if (g_ents_initialized) - if (g_grMode.ConsoleCommand(pl, cmd) == TRUE) + if (g_ents_initialized) { + if (g_grMode.ConsoleCommand(pl, cmd) == TRUE) { return (1); + } + } /* time to handle commands that apply to all games */ tokenize(cmd); @@ -486,19 +502,19 @@ is being executed. float SV_ShouldPause(float newstatus) { - if (serverkeyfloat("background") == 1) { + if (serverinfo.GetFloat("background") == 1) { return (0); } - if (cvar("pausable") == 1) { + if (cvars.GetFloat("pausable") == 1) { return (1); } - if (cvar("sv_playerslots") > 1) { + if (cvars.GetFloat("sv_playerslots") > 1) { return (0); } - return newstatus; + return (newstatus); } //#define REEDICT 1 @@ -652,6 +668,7 @@ SV_PerformSave(float fh, float entcount, float playerslots) num_saved++; } fclose(fh); + NSLog("saved %i entities", num_saved); } @@ -666,6 +683,7 @@ CheckSpawn(void() spawnfunc) NSEntity ent = (NSEntity)self; string desiredClass = ent.classname; static string lastClass; + bool skipLoad = false; /* cancel out early */ if (ent == world) { @@ -680,9 +698,9 @@ CheckSpawn(void() spawnfunc) __fullspawndata = ""; if (MapTweak_EntitySpawn(ent) == true) { - ; + skipLoad = true; } else if (EntityDef_SpawnClassname(desiredClass) != __NULL__) { - ; + skipLoad = true; } else if (spawnfunc) { spawnfunc(); ent.classname = desiredClass; @@ -707,25 +725,19 @@ CheckSpawn(void() spawnfunc) return; } - /* this entity is good, attempt to spawn it. */ - if (ent.m_strSpawnData) { - for (int i = 1; i < (tokenize(ent.m_strSpawnData) - 1); i += 2) { - ent.SpawnKey(argv(i), argv(i+1)); + ent._mapspawned = true; + + if (skipLoad == false) { + /* this entity is good, attempt to spawn it. */ + if (ent.m_strSpawnData) { + for (int i = 1; i < (tokenize(ent.m_strSpawnData) - 1); i += 2) { + ent.SpawnKey(argv(i), argv(i+1)); + } } + + ent.Spawn(); } /* count and mark as map spawned */ - ent._mapspawned = true; g_ent_spawned++; - - /* has to be called once, after the spawn values have been read in. */ - ent.Spawned(); - - /* entity may be marked as deleted */ - if (wasfreed(ent)) { - return; - } - - /* needs to be called at least once after spawn, then any time after. */ - ent.Respawn(); } diff --git a/src/server/include.src b/src/server/include.src index bbe81746..8d3b0056 100644 --- a/src/server/include.src +++ b/src/server/include.src @@ -14,4 +14,5 @@ cmd_cl.qc cmd_sv.qc entry.qc ../nav/includes.src +api.qc #endlist diff --git a/src/server/logging.qc b/src/server/logging.qc index c27e0f98..5f47b9ba 100644 --- a/src/server/logging.qc +++ b/src/server/logging.qc @@ -28,8 +28,8 @@ Logging_Pickup(entity cl, entity it, string altname) } if (altname) { - print(sprintf("%s picked up %s\n", cl.netname, altname)); + printf("%s picked up %s\n", cl.netname, altname); } else { - print(sprintf("%s picked up %s\n", cl.netname, it.classname)); + printf("%s picked up %s\n", cl.netname, it.classname); } } diff --git a/src/server/mapC.h b/src/server/mapC.h deleted file mode 100644 index 294aaee1..00000000 --- a/src/server/mapC.h +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright (c) 2024 Vera Visions LLC. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#pragma target fte_5768 -#define QWSSQC - -/* MapProgs are map specific QuakeC progs. - Include this file with YOUR MapProgs! */ - -#include "../shared/fteextensions.qc" -#include "../shared/global.h" -#include "mapC_math.h" -#include "mapC_weapons.h" - -.float deaths; - -/** @defgroup mapc MapC - @brief MapC/Shared Game-Logic API - @ingroup multiprogs - -APIs used by MapC progs and the server progs exclusively. - -@{ -*/ - -/** Spawns an entity of a specific class. - -This is the primary, encouraged method of spawning entities in MapC. -If you don't spawn an entity class using this, it will not respond to sendInput(). - -If a specified class does not exist, it will create an info_notnull type entity, but with the new, desired classname. - -The only time when this function returns __NULL__ is if the server is unable to allocated any more entities. - -@param className is the type of class to be instantiated. -@param desiredPos is the world position at which the new entity will be placed. */ -entity -spawnClass(string className, vector desiredPos) -{ - entity(string, vector) spawnFunc = externvalue(0, "spawnClass"); - return spawnFunc(className, desiredPos); -} - -bool -changeClass(entity target, string newClass) -{ - bool(entity, string) spawnFunc = externvalue(0, "changeClass"); - return spawnFunc(target, newClass); -} - -bool -cacheEntityDef(string className) -{ - bool(string) spawnFunc = externvalue(0, "EntityDef_Precache"); - return spawnFunc(className); -} - -/** Sends an input (See NSIO::Input) to an entity. - -While you're able to manipulate entities in most ways using bare MapC, you might want to change Nuclide specific attributes of them as well. This can only be done using the I/O system. - -For the variety of inputs an entity supports, please look at the respective entity-specific documentation. - -@param target is the entity which will receive the input -@param inputName is the name of the input. E.g. "SetOrigin" -@param dataString contains parameters for the input. E.g. "0 0 0" -@param activator references which entity is "responsible" for triggering this input. */ -void -sendInput(entity target, string inputName, string dataString, entity activator) -{ - void(entity, string, string, entity) inputFunc = externvalue(0, "sendInput"); - inputFunc(target, inputName, dataString, activator); -} - -/** Applies damage to a given entity. -Requires the use of damageDef/entityDef since we're run out of parameters in QuakeC. - -@param targetEnt is the entity receiving the damage. -@param inflictingEnt is the entity causing the damage (e.g. a projectile, rocket) -@param attackingEnt is the entity owning up to the damage. -@param damageDef is the damageDef containing all the info, including damage points -@param weaponDef is (if not "") the name of the weapon causing the damage. -@param damageOrigin is the location where the damage comes from. -@param damageDir is the direction the damage is coming from. -@param hitLocation is the final hit location, where the damage is applied. */ -void -entityDamage(entity targetEnt, entity inflictingEnt, entity attackingEnt, string damageDef, string weaponDef, vector damageOrigin, vector damageDir, vector hitLocation) -{ - void(entity,entity,entity,string,string,vector,vector,vector) checkFunc = externvalue(0, "entityDamage"); - return checkFunc(targetEnt, inflictingEnt, attackingEnt, damageDef, weaponDef, damageOrigin, damageDir, hitLocation); -} - -/** Does damage to all entities within a specified radius with a linear falloff. -If a negative damageMax value is supplied, then no collision checks will be performed. -So radiusDamage calls will not be obstructed by level or entity geometry. - -@param damageCenter is the location of the center, at which the wave originates. -@param damageRange is the radius (in game units) of the wave. -@param damageMax is the maximum damage that can be done by this wave. -@param damageMin is the minimum amount of damage done, at the very edge. -@param attackingEnt is the entity owning up to the damage. */ -void -radiusDamage(vector damageCenter, float damageRange, int damageMin, int damageMax, entity attackingEnt) -{ - void(vector, float, int, int, entity) checkFunc = externvalue(0, "radiusDamage"); - return checkFunc(damageCenter, damageRange, damageMin, damageMax, attackingEnt); -} - - -/** Returns true/false depending on if the entity is an AI character. - -@param entityToCheck specifies the entity to check.*/ -bool -isAI(entity entityToCheck) -{ - bool(entity) checkFunc = externvalue(0, "isAI"); - return checkFunc(entityToCheck); -} - -/** Returns true/false depending on if the entity is alive. - -@param entityToCheck specifies the entity to check.*/ -bool -isAlive(entity entityToCheck) -{ - bool(entity) checkFunc = externvalue(0, "isAlive"); - return checkFunc(entityToCheck); -} - -/** Returns true/false depending on if the entity is in "god" mode. - -@param entityToCheck specifies the entity to check.*/ -bool -isGodMode(entity entityToCheck) -{ - bool(entity) checkFunc = externvalue(0, "isGodMode"); - return checkFunc(entityToCheck); -} - -/** Returns true/false depending on if the entity is a player. - -@param entityToCheck specifies the entity to check.*/ -bool -isPlayer(entity entityToCheck) -{ - bool(entity) checkFunc = externvalue(0, "isPlayer"); - return checkFunc(entityToCheck); -} - -/** Returns true/false depending on if the entity is either a player, or AI character. - -@param entityToCheck specifies the entity to check.*/ -bool -isSentient(entity entityToCheck) -{ - bool(entity) checkFunc = externvalue(0, "isSentient"); - return checkFunc(entityToCheck); -} - -/** Returns true/false depending on if the entity is a bot. - -@param entityToCheck specifies the entity to check.*/ -bool -isBot(entity entityToCheck) -{ - bool(entity) checkFunc = externvalue(0, "isBot"); - return checkFunc(entityToCheck); -} - -/* misc helper functions. */ - -/** Returns the current time. - -@param realTime specifies the time in seconds since 01/01/1970. -@param zoneType specifies the time zone to use. 0 = UTC, 1 = Local. -@param formatString is a C-language, strftime styled string setting the output format -@return Euler-angles generated from the input. */ -string -timeToString(int realTime, int zoneType, string formatString) -{ - /* supposed to take extra (optional parameters...) */ - if (zoneType == 1i) { - return strftime(true, formatString); - } else { - return strftime(true, formatString); - } -} - -/** Returns the the value of a console variable. - -@param cvarName specifies the console variable to query. -@return The value in string format. */ -string -getCvar(string cvarName) -{ - return cvar_string(cvarName); -} - -/** Returns the the value of a console variable. - -@param cvarName specifies the console variable to query. -@return The value in integer format. */ -int -getCvarInt(string cvarName) -{ - return (int)cvar(cvarName); -} - -/** Returns the the value of a console variable. - -@param cvarName specifies the console variable to query. -@return The value in integer format. */ -bool -fileExists(string fileName) -{ - bool(string) checkFunc = externvalue(0, "fileExists"); - return checkFunc(fileName); -} - -/** Sets the specified serverinfo key to a set value. - -@param serverKey specifies the serverinfo key to set. -@param setValue specifies the value of said key. */ -void -setServerInfo(string serverKey, string setValue) -{ - void(string, string) checkFunc = externvalue(0, "setServerInfo"); - checkFunc(serverKey, setValue); -} - -/** Returns the the value of a serverinfo key. - -@param serverKey specifies the serverinfo key to query. -@return The value in string format. */ -string -getServerInfo(string serverKey) -{ - string(string) checkFunc = externvalue(0, "getServerInfo"); - return checkFunc(serverKey); -} - -/** Sets the specified userinfo key to a set value. - -@param clientEntity specifies the client to poke. -@param userKey specifies the userinfo key to set. -@param setValue specifies the value of said key. */ -void -setUserInfo(entity clientEntity, string userKey, string setValue) -{ - void(entity, string, string) checkFunc = externvalue(0, "setUserInfo"); - checkFunc(clientEntity, userKey, setValue); -} - -/** Returns the the value of a userinfo key. - -@param clientEntity specifies the client to peek at. -@param userKey specifies the userinfo key to query. -@return The value in string format. */ -string -getUserInfo(entity clientEntity, string userKey) -{ - string(entity, string) checkFunc = externvalue(0, "getUserInfo"); - return checkFunc(clientEntity, userKey); -} - -entity -getSpawnpoint(string className) -{ - entity(string) checkFunc = externvalue(0, "Spawn_SelectRandom"); - return checkFunc(className); -} - -entity -placeSpawnpoint(entity targetEntity) -{ - entity(entity) checkFunc = externvalue(0, "placeSpawnpoint"); - return checkFunc(targetEntity); -} - -void -obituary(string A, string B, string C, string D) -{ - void(string, string, string, string) checkFunc = externvalue(0, "obituary"); - checkFunc(A,B,C,D); -} - -void -damage(entity targetEntity, entity inflictingEntity, entity attackingEntity, int damagePoints, int damageFlags, string meansOfDeath, string weaponDef, vector damageOrigin, vector damageDir, string hitLocation, float timeOffset) -{ - -} - -/** @} */ // end of multiprogs \ No newline at end of file diff --git a/src/server/mapC_weapons.h b/src/server/mapC_weapons.h deleted file mode 100644 index 363c246e..00000000 --- a/src/server/mapC_weapons.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2024 Vera Visions LLC. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -/** @defgroup mapc_weapons MapC: Weapons - @brief Server-side plugin wrappers for weapon related functions. - @ingroup multiprogs - - @{ -*/ - -string -weaponType(string weaponDef) -{ - string(string) spawnFunc = externvalue(0, "weaponType"); - return spawnFunc(weaponDef); -} - -int -weaponStartAmmo(string weaponDef) -{ - int(string) spawnFunc = externvalue(0, "weaponStartAmmo"); - return spawnFunc(weaponDef); -} - -int -weaponMaxAmmo(string weaponDef) -{ - int(string) spawnFunc = externvalue(0, "weaponMaxAmmo"); - return spawnFunc(weaponDef); -} - -bool -weaponIsSemiAuto(string weaponDef) -{ - bool(string) spawnFunc = externvalue(0, "weaponIsSemiAuto"); - return spawnFunc(weaponDef); -} - -string -weaponInventoryType(string weaponDef) -{ - string(string) spawnFunc = externvalue(0, "weaponInventoryType"); - return spawnFunc(weaponDef); -} - -float -weaponFireTime(string weaponDef) -{ - float(string) spawnFunc = externvalue(0, "weaponFireTime"); - return spawnFunc(weaponDef); -} - -int -weaponClipSize(string weaponDef) -{ - int(string) spawnFunc = externvalue(0, "weaponClipSize"); - return spawnFunc(weaponDef); -} - -string -weaponClass(string weaponDef) -{ - string(string) spawnFunc = externvalue(0, "weaponClass"); - return spawnFunc(weaponDef); -} - -bool -isWeaponClipOnly(string weaponDef) -{ - bool(string) spawnFunc = externvalue(0, "isWeaponClipOnly"); - return spawnFunc(weaponDef); -} - -bool -isWeaponDetonationTimed(string weaponDef) -{ - bool(string) spawnFunc = externvalue(0, "isWeaponDetonationTimed"); - return spawnFunc(weaponDef); -} - -/** @} */ // end of mapc_weapons diff --git a/src/server/mapcycle.qc b/src/server/mapcycle.qc index 599b7b9e..8418b08a 100644 --- a/src/server/mapcycle.qc +++ b/src/server/mapcycle.qc @@ -32,8 +32,9 @@ Mapcycle_Load(string filename) /* read the lines in, see if the map exists and define an enumerated alias */ while ((temp = fgets(fs_mapcycle))) { - if (fileExists(strcat("maps/", temp, ".bsp")) == false) + if (fileExists(strcat("maps/", temp, ".bsp")) == false) { continue; + } localcmd(sprintf("alias m%i \"map %s;alias nextmap m%i\"\n", mapCount, temp, mapCount + 1i)); @@ -73,7 +74,7 @@ Mapcycle_Init(void) InitStart(); /* in case some server admin wants a map to continously loop */ - if (cycleFile == "") { + if (!STRING_SET(cycleFile)) { NSLog("MapCycle disabled via cvar. Skipping."); localcmd("alias nextmap map_restart 0\n"); return; diff --git a/src/server/maptweaks.qc b/src/server/maptweaks.qc index a9eba526..57a5e85d 100644 --- a/src/server/maptweaks.qc +++ b/src/server/maptweaks.qc @@ -31,6 +31,7 @@ static mapTweak_t *g_mapTweakTable; static int g_mapTweakCount; +const string g_maptweakFile = "scripts/maptweaks.txt"; void MapTweaks_Init(void) @@ -42,7 +43,7 @@ MapTweaks_Init(void) InitStart(); - tweakFile = fopen("scripts/maptweaks.txt", FILE_READ); + tweakFile = fopen(g_maptweakFile, FILE_READ); g_mapTweakCount = 0; tempString = newCvar = newInfo = newItem = ""; @@ -55,7 +56,7 @@ MapTweaks_Init(void) } } } else { - NSError("Missing file scripts/maptweaks.txt"); + NSWarning("No map tweaks, missing %S", g_maptweakFile); InitEnd(); return; } @@ -163,7 +164,7 @@ static bool MapTweak_FinishSpawn(entity targetEntity, string newClassname) { /* found the edef alternative. */ - if (EntityDef_SwitchClass(targetEntity, newClassname) != __NULL__) { + if (ents.ChangeToClass((NSEntity)targetEntity, newClassname) != __NULL__) { return (true); } diff --git a/src/server/scripts.h b/src/server/scripts.h index bf7c1497..a7f6bd54 100644 --- a/src/server/scripts.h +++ b/src/server/scripts.h @@ -21,11 +21,15 @@ void MapC_CallMainFunction(void); void MapC_CallNamedFunction(entity, string); bool RuleC_CallFunc(float, entity, string); +bool RuleC_CallFrame(float, string); bool RuleC_CallDamage(float, entity, entity, entity, string, string); bool RuleC_CallRequestSpawn(float, entity, string); +bool RuleC_CallRequestTeam(float, entity, int, string); bool RuleC_CallString(float, entity, string, string); bool RuleC_CallFloat(float, entity, float, string); +int RuleC_CallMaxItemsPerSlot(float, int, string); +void RuleC_CallInput(float, entity, string, string); diff --git a/src/server/scripts.qc b/src/server/scripts.qc index 5127e21b..9cb807d2 100644 --- a/src/server/scripts.qc +++ b/src/server/scripts.qc @@ -26,12 +26,24 @@ MapC_Init(void) /* No mapname.dat, exit out */ if (fileExists(mapProgs) == false) { - NSError("MapC for level %s at %S does not exist.", mapname, mapProgs); + NSWarning("No MapC for level %s loaded. (%s)", cvar_string("mapname"), mapProgs); return; } NSLog("...adding MapC progs %S",mapProgs); g_mapCProgs = addprogs(mapProgs); + + if (g_mapCProgs > 0) { + void(void) mainFunction; + mainFunction = externvalue(g_mapCProgs, "main"); + + if (mainFunction) { + externset(g_mapCProgs, world, "self"); + mainFunction(); + } else { + NSError("%s does not have a main function.", mapProgs); + } + } } void @@ -82,6 +94,25 @@ RuleC_CallFunc(float progsNum, entity pl, string funcName) return (false); } +bool +RuleC_CallFrame(float progsNum, string funcName) +{ + if (progsNum) { + void(void) mainFunction; + mainFunction = externvalue(progsNum, funcName); + + if (mainFunction) { + entity oldSelf = self; + externset(progsNum, frametime, "frametime"); + self = world; + mainFunction(); + self = oldSelf; + return (true); + } + } + + return (false); +} bool RuleC_CallDamage(float progsNum, entity target, entity inflictor, entity attacker, string weapon, string funcName) @@ -126,6 +157,28 @@ RuleC_CallRequestSpawn(float progsNum, entity pl, string funcName) return (returnValue); } +bool +RuleC_CallRequestTeam(float progsNum, entity pl, int teamNum, string funcName) +{ + bool returnValue = false; + + if (progsNum) { + bool(int) mainFunction; + mainFunction = externvalue(progsNum, funcName); + + if (mainFunction) { + entity oldSelf = self; + externset(progsNum, pl, "self"); + self = pl; + returnValue = mainFunction(teamNum); + self = oldSelf; + return (returnValue); + } + } + + return (returnValue); +} + bool RuleC_CallString(float progsNum, entity pl, string targetString, string funcName) { @@ -169,3 +222,36 @@ RuleC_CallFloat(float progsNum, entity pl, float targetFloat, string funcName) return (returnValue); } + +int +RuleC_CallMaxItemsPerSlot(float progsNum, int targetFloat, string funcName) +{ + int returnValue = -1i; + + if (progsNum) { + int(int) mainFunction; + mainFunction = externvalue(progsNum, funcName); + + if (mainFunction) { + returnValue = mainFunction(targetFloat); + return (returnValue); + } + } + + return (returnValue); +} + + + +void +RuleC_CallInput(float progsNum, entity activator, string inputName, string inputData) +{ + if (progsNum) { + void(entity, string, string) mainFunction; + mainFunction = externvalue(progsNum, "CodeCallback_Input"); + + if (mainFunction) { + mainFunction(activator, inputName, inputData); + } + } +} diff --git a/src/server/skill.qc b/src/server/skill.qc index ffe06746..4d1c6db4 100644 --- a/src/server/skill.qc +++ b/src/server/skill.qc @@ -27,7 +27,7 @@ This will almost always result in them using default values, or (worst case) 0. void Skill_Init(void) { - string mapSkillFile = sprintf("maps/%s_skl.cfg", serverkey("mapname")); + string mapSkillFile = sprintf("maps/%s_skl.cfg", serverinfo.GetString("mapname")); Skill_ParseConfig("cfg/skill_manifest.cfg"); @@ -46,17 +46,17 @@ Return a skill variable's value or return a defaultValue if it's undefined. float Skill_GetValue(string variable, float defaultValue) { - float skill = cvar("skill"); + float skill = cvars.GetFloat("skill"); if (skill == 0) { skill = 2; /* default to medium */ } - float val = fabs(cvar(sprintf("sk_%s%d", variable, skill))); + float val = fabs(cvars.GetFloat(sprintf("sk_%s%d", variable, skill))); /* specific skill variable doesn't exist? */ if (val == 0) { - val = fabs(cvar(sprintf("sk_%s", variable))); + val = fabs(cvars.GetFloat(sprintf("sk_%s", variable))); } return (val == 0) ? defaultValue : val; @@ -71,11 +71,11 @@ Skill_GetStringValue(string variable, string defaultValue) skill = 2; /* default to medium */ } - string val = cvar_string(sprintf("sk_%s%d", variable, skill)); + string val = cvars.GetString(sprintf("sk_%s%d", variable, skill)); /* specific skill variable doesn't exist? */ if (val == 0) { - val = cvar_string(sprintf("sk_%s", variable)); + val = cvars.GetString(sprintf("sk_%s", variable)); } return (val == "") ? defaultValue : val; @@ -101,11 +101,11 @@ Skill_ParseConfig(string fileName) Skill_ParseConfig(sprintf("cfg/%s", argv(1))); } else { /* some games, like Source, don't use set/seta */ - cvar_set(argv(0), argv(1)); + cvars.SetString(argv(0), argv(1)); } } else if (argCount == 3i) { if (firstArg == "set" || firstArg == "seta") - cvar_set(argv(1), argv(2)); + cvars.SetString(argv(1), argv(2)); } } diff --git a/src/server/spawn.qc b/src/server/spawn.qc index b5acc427..eaa3ecb4 100644 --- a/src/server/spawn.qc +++ b/src/server/spawn.qc @@ -142,3 +142,30 @@ entity Spawn_SelectRandom(string cname) lastspot = spot; return spot; } + + +void +Spawn_TeleportToSpawn(entity targetEnt) +{ + string desiredSpawn = teams.SpawnPoint((int)targetEnt.team); + + /* singleplayer */ + if (STRING_SET(startspot)) { + targetEnt.origin = Landmark_GetSpot(); + setorigin_safe(targetEnt, targetEnt.origin); + return; + } + + /* if not set, don't bother teleporting */ + if (!STRING_SET(desiredSpawn)) { + return; + } + + entity spawnPoint = Spawn_SelectRandom(desiredSpawn); + + if (spawnPoint) { + targetEnt.origin = spawnPoint.origin; + targetEnt.angles = spawnPoint.angles; + setorigin_safe(targetEnt, targetEnt.origin); + } +} diff --git a/src/server/vote.qc b/src/server/vote.qc index 20cc8bab..6a5122f0 100644 --- a/src/server/vote.qc +++ b/src/server/vote.qc @@ -39,9 +39,9 @@ Make sure all the cached stuff is reset. void Vote_Reset(void) { - forceinfokey(world, "votes_y", "0"); - forceinfokey(world, "votes_n", "0"); - forceinfokey(world, "vote_cmd", ""); + serverinfo.SetFloat("votes_y", 0); + serverinfo.SetFloat("votes_n", 0); + serverinfo.SetString("vote_cmd", ""); for (entity e = world; (e = find(e, ::classname, "player"));) { NSClientPlayer pl = (NSClientPlayer)e; @@ -95,7 +95,7 @@ Vote_Frame(void) if (time >= g_flVoteTime) { if (g_iVoteState == VOTE_INPROGRESS) { - if (serverkeyfloat("votes_y") > serverkeyfloat("votes_n")) { + if (serverinfo.GetFloat("votes_y") > serverinfo.GetFloat("votes_n")) { Vote_Passed(); } else { Vote_Failed(); @@ -131,7 +131,7 @@ CSEv_VoteY(void) return; } - forceinfokey(world, "votes_y", ftos(serverkeyfloat("votes_y")+1)); + serverinfo.SetFloat("votes_y", serverinfo.GetFloat("votes_y") + 1); pl.voted = 1; /* HACK: Is there a better way to do this? */ @@ -141,12 +141,12 @@ CSEv_VoteY(void) } /* We need at least half the players agreeing. */ - if (serverkeyfloat("votes_y") > rint(playernums / 2)) { + if (serverinfo.GetFloat("votes_y") > rint(playernums / 2)) { Vote_Passed(); return; } - if (serverkeyfloat("votes_n") + serverkeyfloat("votes_y") == playernums) { + if (serverinfo.GetFloat("votes_n") + serverinfo.GetFloat("votes_y") == playernums) { g_flVoteTime = time + 0.0f; } } @@ -176,7 +176,7 @@ CSEv_VoteN(void) return; } - forceinfokey(world, "votes_n", ftos(serverkeyfloat("votes_n")+1)); + serverinfo.SetFloat("votes_n", serverinfo.GetFloat("votes_n") + 1); pl.voted = 1; /* HACK: Is there a better way to do this? */ @@ -186,12 +186,12 @@ CSEv_VoteN(void) } /* We need at least half the players disagreeing. */ - if (serverkeyfloat("votes_n") > rint(playernums / 2)) { + if (serverinfo.GetFloat("votes_n") > rint(playernums / 2)) { Vote_Failed(); return; } - if (serverkeyfloat("votes_n") + serverkeyfloat("votes_y") == playernums) { + if (serverinfo.GetFloat("votes_n") + serverinfo.GetFloat("votes_y") == playernums) { g_flVoteTime = time + 0.0f; } } @@ -218,7 +218,7 @@ Vote_InitiateVote(string votemsg) Vote_Reset(); - forceinfokey(world, "vote_cmd", votemsg); + serverinfo.SetString("vote_cmd", votemsg); g_flVoteTime = time + 30.0f; g_iVoteState = VOTE_INPROGRESS; } diff --git a/src/shared/NSAttack.qc b/src/shared/NSAttack.qc index 48bd1ff4..e020265b 100644 --- a/src/shared/NSAttack.qc +++ b/src/shared/NSAttack.qc @@ -73,7 +73,7 @@ NSAttack::Restore(string strKey, string strValue) m_vecSpread = ReadVector(strValue); break; case "m_weaponOwner": - m_weaponOwner = ReadEntity(strValue); + m_weaponOwner = (NSWeapon)ReadEntity(strValue); break; default: super::Restore(strKey, strValue); diff --git a/src/shared/NSClientPlayer.h b/src/shared/NSClientPlayer.h index 24fc3245..2e3156b7 100644 --- a/src/shared/NSClientPlayer.h +++ b/src/shared/NSClientPlayer.h @@ -71,6 +71,7 @@ public: virtual void VehicleRelink(void); virtual void OnRemoveEntity(void); virtual void ReceiveEntity(float,float); + virtual void _ReceiveComplete(float, float); virtual void PredictPreFrame(void); virtual void PredictPostFrame(void); virtual void ClientInputFrame(void); @@ -99,6 +100,7 @@ public: virtual float SendEntity(entity,float); virtual void Death(entity, entity, int, vector, int); virtual void ServerInputFrame(void); + virtual void Input(entity, string, string); /** Helper function that will optimise the changed-flags of your player entity. */ virtual float OptimiseChangedFlags(entity,float); @@ -119,54 +121,55 @@ public: virtual void Footsteps_Update(void); + nonvirtual void _UpdatePMoveVars(void); + private: #ifdef CLIENT - PREDICTED_INT(weaponframe) - PREDICTED_FLOAT(vehicle_entnum) + NETWORKED_INT(weaponframe) + NETWORKED_FLOAT(vehicle_entnum) #endif #ifdef SERVER - PREDICTED_INT_N(weaponframe) + NETWORKED_INT_N(weaponframe) float nadeCookingTime; #endif - PREDICTED_FLOAT(health) + NETWORKED_FLOAT(health) - PREDICTED_FLOAT_N(colormap) - PREDICTED_FLOAT_N(gflags) - PREDICTED_FLOAT(viewzoom) - PREDICTED_VECTOR_N(view_ofs) - PREDICTED_VECTOR_N(basevelocity) - PREDICTED_VECTOR_N(v_angle) - PREDICTED_FLOAT_N(pmove_flags) + NETWORKED_FLOAT_N(colormap) + NETWORKED_FLOAT_N(gflags) + NETWORKED_FLOAT(viewzoom) + NETWORKED_VECTOR_N(view_ofs) + NETWORKED_VECTOR_N(basevelocity) + NETWORKED_VECTOR_N(v_angle) + NETWORKED_FLOAT_N(pmove_flags) - PREDICTED_FLOAT(w_attack_next) - PREDICTED_FLOAT(w_idle_next) - PREDICTED_FLOAT(w_reload_next) - PREDICTED_FLOAT(teleport_time) - PREDICTED_FLOAT(weapontime) - PREDICTED_FLOAT(m_flStamina) - PREDICTED_VECTOR(punchangle) + NETWORKED_FLOAT(w_attack_next) + NETWORKED_FLOAT(w_idle_next) + NETWORKED_FLOAT(w_reload_next) + NETWORKED_FLOAT(teleport_time) + NETWORKED_FLOAT(weapontime) + NETWORKED_VECTOR(punchangle) /* We can't use the default .items field, because FTE will assume * effects of some bits. Such as invisibility, quad, etc. * also, modders probably want 32 bits for items. */ - PREDICTED_INT(g_items) - PREDICTED_FLOAT_N(activeweapon) + NETWORKED_INT(g_items) + NETWORKED_FLOAT_N(activeweapon) NSItem m_itemList_net; int m_iAmmoTypes_net[MAX_AMMO_TYPES]; /* vehicle info */ - PREDICTED_ENT(vehicle) + NETWORKED_ENT(vehicle) /* these are NOT networked */ int a_ammo1; int a_ammo2; int a_ammo3; - PREDICTED_VECTOR(grapvelocity) + NETWORKED_VECTOR(grapvelocity) #ifdef CLIENT int sequence; @@ -177,6 +180,7 @@ private: int p_model_bone; float lastweapon; #endif + NSPMoveVars m_pmoveVars; #ifdef SERVER int voted; diff --git a/src/shared/NSClientPlayer.qc b/src/shared/NSClientPlayer.qc index 673e2ddb..191dfcd5 100644 --- a/src/shared/NSClientPlayer.qc +++ b/src/shared/NSClientPlayer.qc @@ -102,13 +102,16 @@ NSClientPlayer::IsFakeSpectator(void) bool NSClientPlayer::CanSprint(void) { - return g_pmoveVars.pm_runspeed > 0 ? (true) : false; + if ((IsProne() == true) || (IsCrouching() == true)) + return (false); + + return m_pmoveVars.pm_runspeed > 0 ? (true) : false; } bool NSClientPlayer::CanProne(void) { - return g_pmoveVars.pm_proneheight > 0 ? (true) : false; + return m_pmoveVars.pm_proneheight > 0 ? (true) : false; } bool @@ -120,7 +123,19 @@ NSClientPlayer::CanLean(void) bool NSClientPlayer::CanCrouch(void) { - return g_pmoveVars.pm_crouchheight > 0 ? (true) : false; + return m_pmoveVars.pm_crouchheight > 0 ? (true) : false; +} + +void +NSClientPlayer::_UpdatePMoveVars(void) +{ + if (m_pmoveVars) { + m_pmoveVars.Destroy(); + m_pmoveVars = 0; + } + + m_pmoveVars = spawn(NSPMoveVars); + m_pmoveVars.LinkToEntity(declclass); } void @@ -281,6 +296,8 @@ NSClientPlayer::ProcessInput(void) m_activeWeapon.origin = origin; m_activeWeapon.Relink(); + m_activeWeapon.InputFrame(); + /* weapon system */ if (input_buttons & INPUT_SECONDARY) { m_activeWeapon._SecondaryAttack(); @@ -482,6 +499,9 @@ NSClientPlayer::OnRemoveEntity(void) if (p_model) p_model.Destroy(); + if (m_pmoveVars) + m_pmoveVars.Destroy(); + super::OnRemoveEntity(); } @@ -560,13 +580,6 @@ var float autocvar_cl_forwardspeed = 190; var float autocvar_cl_sidespeed = 152; var float autocvar_cl_backspeed = 133; -/* -================= -NSClientPlayer::ClientInputFrame - -This is basically CSQC_Input_Frame! So games can override this as they please. -================= -*/ void NSClientPlayer::ClientInputFrame(void) { @@ -625,14 +638,6 @@ NSClientPlayer::ClientInputFrame(void) input_buttons |= INPUT_PRONE; } - /* prevent accidental input packets */ - if (pSeat->m_flInputBlockTime > time) { - input_buttons &= ~INPUT_PRIMARY; - input_buttons &= ~INPUT_SECONDARY; - pSeat->m_iInputAttack2 = false; - return; - } - /* some input overrides for XR */ if (XR_Available(this)) { if (pSeat->m_bMoveForward) { @@ -676,15 +681,12 @@ NSClientPlayer::ClientInputFrame(void) } } -/* -================= -NSClientPlayer::ReceiveEntity +void +NSClientPlayer::_ReceiveComplete(float flNew, float flChanged) +{ + +} -Receive the generic client attributes from the server. -If you want to override this, do not call this -at the top of player::ReceiveEntity -================= -*/ void NSClientPlayer::ReceiveEntity(float new, float flChanged) { @@ -701,11 +703,12 @@ NSClientPlayer::ReceiveEntity(float new, float flChanged) if (new) { classname = "player"; - mins = g_pmoveVars.GetStandingMins(); - maxs = g_pmoveVars.GetStandingMaxs(); + mins = m_pmoveVars.GetStandingMins(); + maxs = m_pmoveVars.GetStandingMaxs(); Physics_SetViewParms(); } + READENTITY_INT(entityDefID, PLAYER_MODELINDEX) READENTITY_INT(modelindex, PLAYER_MODELINDEX) READENTITY_BYTE(colormap, PLAYER_MODELINDEX) @@ -773,10 +776,20 @@ NSClientPlayer::ReceiveEntity(float new, float flChanged) READENTITY_INT(m_iAmmoTypes[i], PLAYER_AMMOTYPES) } + /* we only really care about the declclass for decl lookups. */ + if (flChanged & PLAYER_MODELINDEX) { + declclass = EntityDef_NameFromNetID(entityDefID); + } + if (flChanged & PLAYER_SIZE) { setsize(this, mins, maxs); } + /* our decl class has changed. refresh movement values. */ + if (flChanged & PLAYER_MODELINDEX && STRING_SET(declclass)) { + _UpdatePMoveVars(); + } + if (pSeat->m_ePlayer != this) { return; } @@ -796,15 +809,6 @@ NSClientPlayer::ReceiveEntity(float new, float flChanged) } } -/* -================= -NSClientPlayer::PredictPreFrame - -Save the state of the last server-confirmed attributes. -If you want to override this, do not call this -at the top of player::PredictPreFrame -================= -*/ void NSClientPlayer::PredictPreFrame(void) { @@ -875,16 +879,6 @@ NSClientPlayer::PredictPreFrame(void) } } -/* -================= -NSClientPlayer::PredictPostFrame - -After running prediction on the client, roll back the values -to the server's confirmed saved attributes from PredictPreFrame. -If you want to override this, do not call this -at the top of player::PredictPostFrame -================= -*/ void NSClientPlayer::PredictPostFrame(void) { @@ -1097,6 +1091,18 @@ NSClientPlayer::Respawn(void) /* make sure nothing happens here */ } +void +NSClientPlayer::Input(entity eAct, string strInput, string strData) +{ + switch (strInput) { + case "Spectate": + MakeTempSpectator(); + break; + default: + super::Input(eAct, strInput, strData); + } +} + /* ================= NSClientPlayer::MakeTempSpectator @@ -1136,13 +1142,6 @@ NSClientPlayer::MakeTempSpectator(void) forceinfokey(this, "*dead", "0"); } -/* -================= -NSClientPlayer::MakeDead - -Sets all the appropriate attributes to make sure we're dead -================= - */ void NSClientPlayer::Death(entity inflictor, entity attacker, int damage, vector dir, int location) { @@ -1175,16 +1174,19 @@ void NSClientPlayer::Spawned(void) { super::Spawned(); - MakePlayer(); + + /* we really need to check if whether we're a real client yet. */ + if (clienttype(this) == CLIENTTYPE_REAL) { + MakePlayer(); + } else { + Disappear(); /* hide us for now */ + } + +#ifdef SERVER + _UpdatePMoveVars(); +#endif } -/* -================= -NSClientPlayer::MakePlayer - -True participating player, can walk around and everything. -================= - */ void NSClientPlayer::MakePlayer(void) { @@ -1212,7 +1214,7 @@ NSClientPlayer::MakePlayer(void) EnableBleeding(); SetScale(1.0f); Physics_SetViewParms(); - SetSize(g_pmoveVars.GetStandingMins(), g_pmoveVars.GetStandingMaxs()); + SetSize(m_pmoveVars.GetStandingMins(), m_pmoveVars.GetStandingMaxs()); forceinfokey(this, "*spectator", "0"); forceinfokey(this, "*deaths", ftos(deaths)); forceinfokey(this, "*dead", "0"); @@ -1224,24 +1226,16 @@ NSClientPlayer::MakeSpectator(void) { ClientKill(); MakeTempSpectator(); - team = 0; + team = TEAM_SPECTATOR; forceinfokey(this, "*team", ftos(team)); } -/* -================= -NSClientPlayer::EvaluateEntity - -Check which attributes have changed and flag the ones that did. -If you want to override this, do not call this -at the top of player::EvaluateEntity -================= -*/ void NSClientPlayer::EvaluateEntity(void) { pvsflags = !HasVFlags(VFL_FAKESPEC) ? 0 : PVSF_IGNOREPVS; + EVALUATE_FIELD(entityDefID, PLAYER_MODELINDEX) EVALUATE_FIELD(modelindex, PLAYER_MODELINDEX) EVALUATE_FIELD(colormap, PLAYER_MODELINDEX) EVALUATE_FIELD(m_iRenderMode, PLAYER_MODELINDEX) @@ -1306,15 +1300,6 @@ NSClientPlayer::EvaluateEntity(void) } } -/* -================= -NSClientPlayer::SendEntity - -Network any attributes that have been flagged for networking. -If you want to override this, do not call this -at the top of player::SendEntity -================= -*/ float NSClientPlayer::SendEntity(entity ePEnt, float flChanged) { @@ -1329,6 +1314,7 @@ NSClientPlayer::SendEntity(entity ePEnt, float flChanged) WriteByte(MSG_ENTITY, ENT_PLAYER); WriteFloat(MSG_ENTITY, flChanged); + SENDENTITY_INT(entityDefID, PLAYER_MODELINDEX) SENDENTITY_INT(modelindex, PLAYER_MODELINDEX) SENDENTITY_BYTE(colormap, PLAYER_MODELINDEX) @@ -1424,19 +1410,12 @@ NSClientPlayer::OptimiseChangedFlags(entity ePEnt, float flChanged) } else { /* always keep us alive to ourselves or the person spectating */ /* this will make prediction smoother */ - flChanged |= PLAYER_MODELINDEX; + //flChanged |= PLAYER_MODELINDEX; } return flChanged; } -/* -==================== -_NSClientPlayer_useworkaround - -A wrapper to cleanly reset 'self' as to not mess up the QC VM -==================== -*/ void _NSClientPlayer_useworkaround(entity eTarget) { @@ -1447,13 +1426,7 @@ _NSClientPlayer_useworkaround(entity eTarget) self = eOldSelf; } -/* -==================== -_NSClientPlayer_useworkaround -A wrapper to cleanly reset 'self' as to not mess up the QC VM -==================== -*/ void _NSClientPlayer_unuseworkaround(entity eTarget) { @@ -1465,14 +1438,6 @@ _NSClientPlayer_unuseworkaround(entity eTarget) self = eOldSelf; } -/* -================= -NSClientPlayer:: InputUse_Down - -Called when we hold down the +use button for the first time, -looks for an entity that has the .PlayerUse field set to a function and calls it. -================= -*/ void NSClientPlayer::InputUse_Down(void) { @@ -1525,13 +1490,6 @@ NSClientPlayer::InputUse_Down(void) } } -/* -================= -NSClientPlayer:: InputUse_Down - -Called when we let go of the +use button -================= -*/ void NSClientPlayer::InputUse_Up(void) { @@ -1768,10 +1726,10 @@ NSClientPlayer::Damage(entity inflictor, entity attacker, NSDict damageDecl, flo /* they died */ if (GetHealth() <= 0) { - g_grMode.PlayerDeath(this, attacker, damageDecl); + g_grMode.PlayerDeath(this, (NSActor)attacker, damageDecl); Death(inflictor, attacker, (int)damagePoints, dmgDir, 0i); } else { - g_grMode.PlayerPain(this, attacker, damageDecl); + g_grMode.PlayerPain(this, (NSActor)attacker, damageDecl); Pain(inflictor, attacker, (int)damagePoints, dmgDir, 0i); } #endif diff --git a/src/shared/NSDict.h b/src/shared/NSDict.h index 53583a6a..a583ea73 100644 --- a/src/shared/NSDict.h +++ b/src/shared/NSDict.h @@ -43,6 +43,7 @@ NSDict public: void NSDict(void); + nonvirtual int GetInteger(string); nonvirtual float GetFloat(string); nonvirtual string GetString(string); nonvirtual vector GetVector(string); @@ -54,11 +55,14 @@ public: nonvirtual void AddKey(string, string); nonvirtual void RemoveKey(string); - nonvirtual NSDict InitWithSpawnData(string); + nonvirtual int TokenCount(void); + + static NSDict InitWithSpawnData(string); + static NSDict LoadDeclFromFile(string, string); private: nonvirtual void _AddRemoveKey(string, string, bool); string m_strBody; }; -/** @} */ // end of decl \ No newline at end of file +/** @} */ // end of decl diff --git a/src/shared/NSDict.qc b/src/shared/NSDict.qc index 9bae91b4..3c5bcc44 100644 --- a/src/shared/NSDict.qc +++ b/src/shared/NSDict.qc @@ -32,6 +32,12 @@ NSDict::SetDeclBody(string textBody) m_strBody = textBody; } +int +NSDict::GetInteger(string keyName) +{ + return (int)stoi(GetString(keyName)); +} + float NSDict::GetFloat(string keyName) { @@ -97,6 +103,12 @@ NSDict::RemoveKey(string keyName) _AddRemoveKey(keyName, "", true); } +int +NSDict::TokenCount(void) +{ + return (int)tokenize_console(m_strBody); +} + NSDict NSDict::InitWithSpawnData(string spawnData) { @@ -104,3 +116,87 @@ NSDict::InitWithSpawnData(string spawnData) newDict.SetDeclBody(spawnData); return (newDict); } + +NSDict +NSDict::LoadDeclFromFile(string declName, string fileName) +{ + filestream fh; + NSDict newDict; + string tempString; + int braceDepth = 0i; + string lastWord = __NULL__; + string lastDecl = ""; + + fh = fopen(strcat("decls/", fileName), FILE_READ); + + if (fh < 0) { + NSError("Can't read %S", fileName); + return __NULL__; + } + + newDict = spawn(NSDict); + + while ((tempString = fgets(fh))) { + int lineSegments = tokenize_console(tempString); + + for (int i = 0i; i < lineSegments; i++) { + string word = argv(i); + + switch (word) { + case "{": + braceDepth++; + break; + case "}": + braceDepth--; + + /* we've reached the end of a definition */ + if (braceDepth == 0) { + /* we found it, we're done */ + if (STRING_SET(lastDecl) && lastDecl == declName) { + break; + } + lastDecl = ""; + } + break; + default: + /* anything outside braces defines the classname for the next def */ + if (braceDepth == 0 && lastWord == "typeInfo") { + lastDecl = word; + } /* else if (braceDepth == 0 && lastWord == "#include") { + g_entDefInclude = strcat(g_entDefInclude, word, ";"); + } else if (braceDepth == 0 && lastWord == "#define") { + Constants_Add(argv(i), argv(i+1)); + } */ else if (braceDepth == 1) { + /* spawnclass is reserved and the next keyword specs it */ + /*if (word == "spawnclass") { + currentDef.spawnClass = argv(i+1); + i++; + } else if (word == "inherit") { + currentDef.inheritKeys = argv(i+1); + i++; + } else*/ if (lastDecl == declName) { /* rest gets dumped into spawndata */ + newDict.m_strBody = strcat(newDict.m_strBody, "\"", word, "\"", " "); + } + } + } + lastWord = word; + } + +#if 0 + if (c == 1) { + + } else if (c == 2) { + newDict.AddKey(argv(0), argv(1)); + } +#endif + } + + /* failed to find any key-value pairs. empty */ + if (!STRING_SET(newDict.m_strBody)) { + remove(newDict); + return (__NULL__); + } + + return (newDict); +} + diff --git a/src/shared/NSEntity.h b/src/shared/NSEntity.h index 3f5f40af..6f709fdb 100644 --- a/src/shared/NSEntity.h +++ b/src/shared/NSEntity.h @@ -75,6 +75,7 @@ public: /* overrides */ virtual void SpawnKey(string,string); virtual void Spawned(void); + nonvirtual void Spawn(void); /** Tells the engine to make the entity static, effectively making it inaccessible. It will be removed from the game-logic but remain visible and it will retain its @@ -398,30 +399,35 @@ private: bool m_bIsBrush; vector m_vecEditorColor; - PREDICTED_FLOAT(entityDefID) - PREDICTED_VECTOR_N(origin) - PREDICTED_VECTOR_N(angles) - PREDICTED_FLOAT_N(modelindex) - PREDICTED_VECTOR_N(size) - PREDICTED_VECTOR_N(mins) - PREDICTED_VECTOR_N(maxs) - PREDICTED_FLOAT_N(solid) - PREDICTED_FLOAT_N(movetype) - PREDICTED_FLOAT_N(scale) - PREDICTED_FLOAT_N(flags) - PREDICTED_FLOAT_N(vv_flags) - PREDICTED_VECTOR_N(velocity) - PREDICTED_VECTOR_N(avelocity) + NETWORKED_INT(entityDefID) + NETWORKED_VECTOR_N(origin) + NETWORKED_VECTOR_N(angles) + NETWORKED_FLOAT_N(modelindex) + NETWORKED_VECTOR_N(size) + NETWORKED_VECTOR_N(mins) + NETWORKED_VECTOR_N(maxs) + NETWORKED_FLOAT_N(solid) + NETWORKED_FLOAT_N(movetype) + NETWORKED_FLOAT_N(scale) + NETWORKED_FLOAT_N(flags) + NETWORKED_FLOAT_N(vv_flags) + NETWORKED_VECTOR_N(velocity) + NETWORKED_VECTOR_N(avelocity) + +#ifdef CLIENT + /** Called once ReceiveEntity has done its job. */ + virtual void _ReceiveComplete(float, float); +#endif + #ifdef SERVER string m_parent; string m_parent_old; string m_parent_attachment; - PREDICTED_FLOAT_N(frame) - PREDICTED_FLOAT_N(skin) - PREDICTED_FLOAT_N(effects) + NETWORKED_FLOAT_N(frame) + NETWORKED_FLOAT_N(skin) + NETWORKED_FLOAT_N(effects) #endif - /** Will read from the named def to perform a projectile attack. */ nonvirtual bool _ProjectileAttack(string, bool); }; @@ -430,6 +436,10 @@ private: unless we're seriously out of memory. */ NSEntity spawnClass(string className, vector desiredPos); +#ifdef SERVER +bool changeClass(entity target, string className) +#endif + void sendInput(entity target, string inputName, string dataString, entity activator); bool isAI(entity entityToCheck); @@ -445,3 +455,7 @@ bool isPlayer(entity entityToCheck); bool isSentient(entity entityToCheck); bool isBot(entity entityToCheck); + +bool isItem(entity entityToCheck); + +bool isWeapon(entity entityToCheck); diff --git a/src/shared/NSEntity.qc b/src/shared/NSEntity.qc index 01f81fe2..6ecce908 100644 --- a/src/shared/NSEntity.qc +++ b/src/shared/NSEntity.qc @@ -33,6 +33,18 @@ NSEntity::NSEntity(void) m_vecEditorColor = [1,1,1]; } +void +NSEntity::Spawn(void) +{ + Spawned(); + + if (wasfreed(this)) { + return; + } + + Respawn(); +} + void NSEntity::Spawned(void) { @@ -227,6 +239,12 @@ NSEntity::ReceiveEntity(float flNew, float flChanged) } } +void +NSEntity::_ReceiveComplete(float flNew, float flChanged) +{ + +} + void NSEntity::ReceiveEvent(float eventType) { @@ -1042,7 +1060,7 @@ NSEntity::Input(entity eAct, string strInput, string strData) break; case "SpawnProjectileDef": if (EntityDef_HasSpawnClass(strData)) { - NSProjectile_SpawnDefAttachment(strData, this, 0); + NSProjectile_SpawnDefAttachment(strData, (NSActor)this, 0); } break; case "StartSoundDef": @@ -1436,7 +1454,7 @@ NSEntity::_ProjectileAttack(string defName, bool wasReleased) for (int i = 0i; i < numProjectiles; i++) { EntLog("Launching %S at %v towards %v", attackDef, GetEyePos(), GetViewAngle()); - NSAttack_SpawnDefAtPosition(attackDef, this, GetEyePos(), GetViewAngle()); + NSAttack_SpawnDefAtPosition(attackDef, (NSActor)this, GetEyePos(), GetViewAngle()); } #endif @@ -1488,156 +1506,3 @@ NSEntity::DisablePlayerCollision(void) dimension_solid = 1; dimension_hit = 1; } - -NSEntity -spawnClass(string className, vector desiredPos) -{ - NSEntity newEntity = __NULL__; - -#ifdef SERVER - newEntity = Entity_CreateClass(className); - - /* That class didn't exist, so let's take the base Nuclide one */ - if (!newEntity) { - newEntity = Entity_CreateClass("NSEntity"); - } - - /* OOM. It's over. */ - if (!newEntity) { - return (__NULL__); - } - - newEntity.classname = className; - newEntity.Input(newEntity, "SetOrigin", vtos(desiredPos)); - newEntity.Respawn(); -#endif - - return (newEntity); -} - -#ifdef SERVER -bool -changeClass(entity target, string className) -{ - return EntityDef_SwitchClass((NSEntity)target, className) ? (true) : (false); -} -#endif - -void -sendInput(entity target, string inputName, string dataString, entity activator) -{ - NSEntity targetEntity = (NSEntity)target; -#ifdef SERVER - targetEntity.Input(activator, inputName, dataString); -#endif -} - -/* helper functions */ -bool -isAI(entity entityToCheck) -{ - if (entityToCheck.flags & FL_MONSTER) { - return (true); - } - - return (false); -} - -bool -isAlive(entity entityToCheck) -{ -#ifdef SERVER - if (entityToCheck.takedamage != DAMAGE_NO) { - NSSurfacePropEntity livingEnt = (NSSurfacePropEntity)entityToCheck; - return livingEnt.IsAlive(); - } -#endif - - return (false); -} - -bool -isGodMode(entity entityToCheck) -{ - if (entityToCheck.flags & FL_GODMODE) { - return (true); - } - - return (false); -} - -bool -isClient(entity entityToCheck) -{ - return (entityToCheck.flags & FL_CLIENT) ? (true) : (false); -} - -bool -isPlayer(entity entityToCheck) -{ - if (isClient(entityToCheck)) { - NSClient pl = (NSClient)entityToCheck; - - return pl.IsPlayer(); - } - - return (false); -} - -bool -isSentient(entity entityToCheck) -{ - if (isAI(entityToCheck) || isPlayer(entityToCheck)) { - return (true); - } - - return (false); -} - -bool -isBot(entity entityToCheck) -{ -#ifdef SERVER - return (clienttype(entityToCheck) == CLIENTTYPE_BOT) ? (true) : (false); -#else - return (false); -#endif -} - - -#ifdef SERVER -void -setUserInfo(entity clientEntity, string serverKey, string setValue) -{ - if (isClient(clientEntity)) { - NSClient client = (NSClient) clientEntity; - client.SetInfoKey(serverKey, setValue); - } -} - -string -getUserInfo(entity clientEntity, string serverKey) -{ - if (isClient(clientEntity)) { - NSClient client = (NSClient) clientEntity; - return client.GetInfoKey(serverKey); - } -} -#endif - -void -placeSpawnpoint(entity target) -{ - vector testorg = target.origin; - - for (int i = 0; i < 32; i++) { - tracebox(testorg, target.mins, target.maxs, testorg, MOVE_NORMAL, target); - - if (!trace_startsolid) { - setorigin(target, testorg); - break; - } - - testorg[2] += 1.0; - } -} diff --git a/src/shared/NSIO.h b/src/shared/NSIO.h index 602b1b4d..d75b3a93 100644 --- a/src/shared/NSIO.h +++ b/src/shared/NSIO.h @@ -184,8 +184,11 @@ public: nonvirtual void DebugBool(string,bool); /** Debug print for a given entity. */ nonvirtual void DebugEntity(string,entity); + /** Sets the editor icon. Must be 16x16 px and located in `gfx/icon16/`. */ + nonvirtual void SetEditorIcon(string); private: + string m_strEditorIcon; string m_strSpawnData; #ifdef SERVER string m_strOnTrigger; @@ -199,6 +202,7 @@ private: #endif }; +.bool isActor; .bool _mapspawned; void diff --git a/src/shared/NSIO.qc b/src/shared/NSIO.qc index e8c51188..755992df 100644 --- a/src/shared/NSIO.qc +++ b/src/shared/NSIO.qc @@ -38,6 +38,8 @@ NSIO::NSIO(void) isCSQC = TRUE; effects |= EF_NOSHADOW; #endif + m_strEditorIcon = "gfx/icon16/bullet_purple"; + isActor = false; } void @@ -59,6 +61,9 @@ NSIO::Spawned(void) if (m_strOnUser4) m_strOnUser4 = CreateOutput(m_strOnUser4); #endif + + _isWeapon = false; + _isItem = false; } void @@ -69,7 +74,6 @@ NSIO::OnRemoveEntity(void) void NSIO::Destroy(void) { - removed = 1; /* mark this as cleanly removed */ OnRemoveEntity(); customphysics = __NULL__; modelindex = 0; @@ -78,24 +82,13 @@ NSIO::Destroy(void) classname = 0; think = __NULL__; nextthink = 0.0f; + identity = 1; + _isWeapon = false; + _isItem = false; + removed = true; remove(this); } -float -NSIO::GetDefAct(string keyName) -{ - float randomValue; - string actValue = EntityDef_GetKeyValue(classname, keyName); - float actCount = tokenizebyseparator(actValue, ","); - - if (actCount == 1) { - return stof(actValue); - } else { - randomValue = floor(pseudorandom() * actCount); - return stof(argv(randomValue)); - } -} - string NSIO::GetDefString(string keyName) { @@ -140,25 +133,31 @@ NSIO::GetSubDefAct(string subDef, string activityName) /* not in class decl either. look it up in the model */ if (!STRING_SET(fireValue)) { - /* look it up in the model itself now */ - float actModelNum = stof(EntityDef_GetKeyValue("activities", actNameCheck)); - float frameGroup = frameforaction(modelindex, actModelNum); - return (frameGroup); - //return (-1); - } + string actValue = EntityDef_GetKeyValue("activities", actNameCheck); - actCount = tokenizebyseparator(fireValue, ","); - - if (actCount == 1) { - return stof(fireValue); + if (STRING_SET(actValue)) { + /* look it up in the model itself now */ + float actModelNum = stof(actValue); + float frameGroup = frameforaction(modelindex, actModelNum); + return (frameGroup); + } } else { - float randomValue = floor(pseudorandom() * actCount); - return stof(argv(randomValue)); + actCount = tokenizebyseparator(fireValue, ","); + + if (actCount == 1) { + return stof(fireValue); + } else { + float randomValue = floor(pseudorandom() * actCount); + return stof(argv(randomValue)); + } } + + /* not in fireInfo, not in model... skip! */ + return (-1); } float -NSIO::GetAct(string activityName) +NSIO::GetDefAct(string activityName) { return GetSubDefAct(classname, activityName); } @@ -556,6 +555,7 @@ NSIO::Save(float handle) SaveString(handle, "m_strOnUser4", m_strOnUser4); SaveString(handle, "m_strModelEventCB", m_strModelEventCB); SaveString(handle, "m_strSpawnData", m_strSpawnData); + SaveString(handle, "m_strEditorIcon", m_strEditorIcon); } void NSIO::Restore(string strKey, string strValue) @@ -851,6 +851,9 @@ NSIO::Restore(string strKey, string strValue) case "m_strSpawnData": m_strSpawnData = ReadString(strValue); break; + case "m_strEditorIcon": + m_strEditorIcon = ReadString(strValue); + break; } } @@ -885,6 +888,9 @@ NSIO::SpawnKey(string strKey, string strValue) case "targetname": targetname = strValue; break; + case "editor_icon": + m_strEditorIcon = ReadString(strValue); + break; #ifdef SERVER /* Input/Output system */ case "OnTrigger": @@ -956,3 +962,8 @@ NSIO::DebugEntity(string key, entity targ) float value = num_for_edict(targ); EntLog("%S \"%f\"", key, value); } +void +NSIO::SetEditorIcon(string newIcon) +{ + m_strEditorIcon = strcat("gfx/icon16/", newIcon); +} diff --git a/src/shared/NSItem.h b/src/shared/NSItem.h index 04a73ebe..2ba91fb4 100644 --- a/src/shared/NSItem.h +++ b/src/shared/NSItem.h @@ -75,6 +75,7 @@ public: virtual void Touch(entity); virtual void Respawn(void); virtual void SpawnKey(string, string); + virtual void Input(entity, string, string); virtual void Save(float); virtual void Restore(string,string); virtual void EvaluateEntity(void); @@ -93,6 +94,9 @@ public: /** Overridable: Called when this item is picked up. */ virtual void OnPickup(void); + /** Overridable: Called when this item is used. */ + virtual void OnUse(entity); + virtual void PrintDebugInfo(void); /** Call to turn a weapon into a pickup. */ nonvirtual void BecomePickup(void); diff --git a/src/shared/NSItem.qc b/src/shared/NSItem.qc index 58cbfd66..f611c4ec 100644 --- a/src/shared/NSItem.qc +++ b/src/shared/NSItem.qc @@ -42,24 +42,12 @@ NSItem::Spawned(void) Sound_Precache(m_sndAcquire); Sound_Precache(m_sndRespawn); pvsflags = PVSF_IGNOREPVS; + _isItem = true; } void NSItem::Respawn(void) { - /* we need to delay the DropToFloor() by at least a frame. - otherwise they may just fall through an entity (func_wall, func_train etc.) - that came after this entity in the lump. */ - static void AdjustSpawnPos(void) { - RestoreAngles(); - SetOrigin(GetSpawnVector("origin")); - placeSpawnpoint(this); - - if (!m_bFloating) { - DropToFloor(); - } - } - super::Respawn(); BecomePickup(); @@ -67,7 +55,12 @@ NSItem::Respawn(void) EnablePlayerCollision(); if (CreatedByMap() == true) { - ScheduleThink(AdjustSpawnPos, 0.0f); + RestoreAngles(); + SetOriginUnstick(GetSpawnVector("origin")); + + if (!m_bFloating) { + DropToFloor(); + } } } @@ -210,6 +203,21 @@ NSItem::Restore(string strKey, string strValue) } } +void +NSItem::Input(entity eAct, string strInput, string strData) +{ + switch (strInput) { + default: + NSTrigger::Input(eAct, strInput, strData); + } +} + +void +NSItem::OnUse(entity user) +{ + +} + bool NSItem::ItemPickupCheck(entity pickerUpper) { @@ -401,7 +409,7 @@ NSItem::SendEntity(entity ePEnt, float flChanged) SENDENTITY_ANGLE(angles[0], ITEMFL_CHANGED_ANGLES_X) SENDENTITY_ANGLE(angles[1], ITEMFL_CHANGED_ANGLES_Y) SENDENTITY_ANGLE(angles[2], ITEMFL_CHANGED_ANGLES_Z) - SENDENTITY_FLOAT(entityDefID, ITEMFL_CHANGED_MODELINDEX) + SENDENTITY_INT(entityDefID, ITEMFL_CHANGED_MODELINDEX) SENDENTITY_SHORT(modelindex, ITEMFL_CHANGED_MODELINDEX) SENDENTITY_BYTE(solid, ITEMFL_CHANGED_SOLID) SENDENTITY_BYTE(movetype, ITEMFL_CHANGED_FLAGS) @@ -489,7 +497,7 @@ NSItem::ReceiveEntity(float flNew, float flChanged) READENTITY_ANGLE(angles[0], ITEMFL_CHANGED_ANGLES_X) READENTITY_ANGLE(angles[1], ITEMFL_CHANGED_ANGLES_Y) READENTITY_ANGLE(angles[2], ITEMFL_CHANGED_ANGLES_Z) - READENTITY_FLOAT(entityDefID, ITEMFL_CHANGED_MODELINDEX) + READENTITY_INT(entityDefID, ITEMFL_CHANGED_MODELINDEX) READENTITY_SHORT(modelindex, ITEMFL_CHANGED_MODELINDEX) READENTITY_BYTE(solid, ITEMFL_CHANGED_SOLID) READENTITY_BYTE(movetype, ITEMFL_CHANGED_FLAGS) @@ -626,7 +634,7 @@ NSItem::_AddedCallback(void) { NSActor ourOwner = (NSActor)owner; -#ifdef CLIENT +#if 0 if (pSeat->m_ePlayer == owner) { localcmd("bf\n"); } @@ -657,11 +665,13 @@ NSItem::_AddedCallback(void) Logging_Pickup(ourOwner, this, __NULL__); ourOwner.StartSoundDef(m_sndAcquire, CHAN_ITEM, true); OnPickup(); - Disappear(); + MakeInvulnerable(); #endif + Disappear(); ourOwner.AddedItemCallback(this); AddedToInventory(); + SetMovetype(MOVETYPE_NONE); } void diff --git a/src/shared/NSMonster.h b/src/shared/NSMonster.h index 2717ad90..5b3a829f 100644 --- a/src/shared/NSMonster.h +++ b/src/shared/NSMonster.h @@ -339,6 +339,14 @@ public: virtual void RouteEnded(void); /** Internal use only. Called every frame to progress through a route. */ virtual void WalkRoute(void); + + /* callbacks */ + /** Called when a player is seen by the monster. */ + virtual void SeenPlayer(NSActor); + /** Called when an enemy is seen by the monster. */ + virtual void SeenEnemy(NSActor); + /** Called when a friend is seen by the monster. */ + virtual void SeenFriend(NSActor); /** Returns the type of sequence they're currently in. */ nonvirtual int GetSequenceState(void); diff --git a/src/shared/NSMonster.qc b/src/shared/NSMonster.qc index 4ce6065d..443f190e 100644 --- a/src/shared/NSMonster.qc +++ b/src/shared/NSMonster.qc @@ -449,19 +449,19 @@ NSMonster::Restore(string strKey, string strValue) int NSMonster::AnimIdle(void) { - return GetAct("idle"); + return GetDefAct("idle"); } int NSMonster::AnimWalk(void) { - return GetAct("walk"); + return GetDefAct("walk"); } int NSMonster::AnimRun(void) { - float runAnim = GetAct("run"); + float runAnim = GetDefAct("run"); return (runAnim == -1) ? AnimWalk() : runAnim; } @@ -642,6 +642,21 @@ NSMonster_TraceAgainsTarget(NSMonster monster, NSEntity target) return false; } +void +NSMonster::SeenPlayer(NSActor theActor) +{ +} + +void +NSMonster::SeenEnemy(NSActor theActor) +{ +} + +void +NSMonster::SeenFriend(NSActor theActor) +{ +} + void NSMonster::SeeThink(void) { @@ -713,14 +728,10 @@ NSMonster::SeeThink(void) } /* iterate through all players, monsters. */ - for (entity w = world; (w = nextent(w));) { + for (entity w = world; (w = findfloat(w, ::isActor, 1));) { if (w.takedamage == DAMAGE_NO) continue; - /* check if 'w' could be a valid enemy */ - if (IsValidEnemy(w) == false) - continue; - /* first, is the potential enemy in our field of view? */ vector v = normalize(w.origin - GetEyePos()); float flDot = v * anglesToForward(angles); @@ -728,15 +739,22 @@ NSMonster::SeeThink(void) if (flDot < SeeFOV()/180) continue; - /* we have line of sight with the player */ + /* we have line of sight with the entity */ if (NSMonster_TraceAgainsTarget(this, (NSEntity)w) == true) { - if (m_eEnemy != w) { - m_eEnemy = w; - m_flTrackingTime = time; - _Alerted(); - AlertNearby(); + /* check if 'w' could be a valid enemy */ + if (IsValidEnemy(w) == true) { + if (m_eEnemy != w) { + SeenEnemy((NSActor)w); + m_eEnemy = w; + m_flTrackingTime = time; + _Alerted(); + AlertNearby(); + } + } else if (isPlayer(w)) { + SeenPlayer((NSActor)w); + } else if (IsFriend(w.m_iAlliance)) { + SeenFriend((NSActor)w); } - return; } } } @@ -789,9 +807,9 @@ NSMonster::_LerpTurnToYaw(vector turnYaw) if (m_bTurning == false) { if (yawDiff < 0) { - AnimPlay(GetAct("turnRight")); + AnimPlay(GetDefAct("turnRight")); } else { - AnimPlay(GetAct("turnLeft")); + AnimPlay(GetDefAct("turnLeft")); } } @@ -980,7 +998,7 @@ NSMonster::AttackRanged(void) float rangedMax = GetSubDefFloat(m_defRanged1, "delay_max"); float burstCount = GetSubDefFloat(m_defRanged1, "burst"); float burstDelay = GetSubDefFloat(m_defRanged1, "burst_delay"); - float actRanged = GetAct("rangeAttack1"); + float actRanged = GetDefAct("rangeAttack1"); float burstTime = 0.0f; if (rangedDly <= 0.0) { @@ -991,7 +1009,7 @@ NSMonster::AttackRanged(void) if (m_flReloadCount) if (_m_flReloadTracker > m_flReloadCount) { float startAmmo = 0; - float actReload = GetAct("reload"); + float actReload = GetDefAct("reload"); /* out of ammo, cannot reload */ if (m_flReserveAmmo == 0) { @@ -1061,7 +1079,7 @@ NSMonster::AttackRanged(void) return 1; } else if (throwAnyway == false && inRanged2Range && trace_ent == m_eEnemy) { - float actRangedSpecial = GetAct("rangeAttack2"); + float actRangedSpecial = GetDefAct("rangeAttack2"); AnimReset(); AnimPlay(actRangedSpecial); ScheduleThink(AttackRanged_RangedSpecial, 0.0f); @@ -1069,7 +1087,7 @@ NSMonster::AttackRanged(void) return 1; } else if (inSpecial1Range) { AnimReset(); - AnimPlay(GetAct("specialAttack1")); + AnimPlay(GetDefAct("specialAttack1")); ScheduleThink(AttackRanged_Throw, m_flProjectileDelay); if (_m_bShouldThrow) @@ -1080,7 +1098,7 @@ NSMonster::AttackRanged(void) return 1; } else if (inSpecial2Range) { AnimReset(); - AnimPlay(GetAct("specialAttack2")); + AnimPlay(GetDefAct("specialAttack2")); ScheduleThink(AttackRanged_Throw, m_flProjectileDelay); if (_m_bShouldThrow) @@ -1098,7 +1116,7 @@ NSMonster::AttackRanged(void) void NSMonster::AttackDraw(void) { - float actDraw = GetAct("arm"); + float actDraw = GetDefAct("arm"); AnimPlay(actDraw); m_flAttackThink = time + frameduration(modelindex, actDraw); @@ -1116,7 +1134,7 @@ NSMonster::AttackDraw(void) void NSMonster::AttackHolster(void) { - float actHolster = GetAct("disarm"); + float actHolster = GetDefAct("disarm"); AnimPlay(actHolster); m_flAttackThink = time + frameduration(modelindex, actHolster); } @@ -1309,7 +1327,7 @@ NSMonster::AnimationUpdate(void) m_flAnimTime = 0.0f; if (fr == -1) - act = GetAct("idle"); + act = GetDefAct("idle"); m_iMoveState = MOVESTATE_IDLE; @@ -1320,7 +1338,7 @@ NSMonster::AnimationUpdate(void) m_flAnimTime = 0.0f; if (fr == -1) - act = GetAct("walk"); + act = GetDefAct("walk"); m_iMoveState = MOVESTATE_WALK; @@ -1331,7 +1349,7 @@ NSMonster::AnimationUpdate(void) m_flAnimTime = 0.0f; if (fr == -1) - act = GetAct("run"); + act = GetDefAct("run"); m_iMoveState = MOVESTATE_RUN; } @@ -1433,11 +1451,6 @@ NSMonster::Physics(void) return; } - /* HACK!!! */ - if (!IsAlive()) { - return; - } - /* editors like Hammer like putting 'sequence' into spawndata of monsters. so only ever force the animation when flagged as dead */ if (_m_bStartDead && m_flForceSequence) { @@ -1447,6 +1460,12 @@ NSMonster::Physics(void) m_flAnimTime = time + 999.0f; frame = m_flForceSequence; m_iSequenceState = SEQUENCESTATE_IDLE; + return; + } + + /* HACK!!! */ + if (!IsAlive()) { + return; } /* unset the leap attack */ @@ -1576,9 +1595,9 @@ NSMonster::HasBeenHit(void) void NSMonster::Pain(entity inflictor, entity attacker, int damage, vector dir, int location) { - float actSmallFlinch = GetAct("smallFlinch"); - float actBigFlinch = GetAct("bigFlinch"); - float actTwitch = GetAct("twitch"); + float actSmallFlinch = GetDefAct("smallFlinch"); + float actBigFlinch = GetDefAct("bigFlinch"); + float actTwitch = GetDefAct("twitch"); float actPain = -1; float baseHealth = GetSpawnFloat("health"); @@ -1616,25 +1635,25 @@ NSMonster::Pain(entity inflictor, entity attacker, int damage, vector dir, int l switch (location) { case BODY_HEAD: - actPain = GetAct("flinchHead"); + actPain = GetDefAct("flinchHead"); break; case BODY_CHEST: - actPain = GetAct("flinchChest"); + actPain = GetDefAct("flinchChest"); break; case BODY_STOMACH: - actPain = GetAct("flinchStomach"); + actPain = GetDefAct("flinchStomach"); break; case BODY_ARMLEFT: - actPain = GetAct("flinchLeftArm"); + actPain = GetDefAct("flinchLeftArm"); break; case BODY_ARMRIGHT: - actPain = GetAct("flinchRightArm"); + actPain = GetDefAct("flinchRightArm"); break; case BODY_LEGLEFT: - actPain = GetAct("flinchLeftLeg"); + actPain = GetDefAct("flinchLeftLeg"); break; case BODY_LEGRIGHT: - actPain = GetAct("flinchRightLeg"); + actPain = GetDefAct("flinchRightLeg"); break; } @@ -1684,11 +1703,11 @@ NSMonster::Death(entity inflictor, entity attacker, int damage, vector dir, int StartSoundDef(m_sndThud, CHAN_BODY, true); } - float actViolent = GetAct("dieViolent"); - float actForward = GetAct("dieForward"); - float actBackward = GetAct("dieBackward"); - float actSimple = GetAct("dieSimple"); - float actBackshot = GetAct("dieBackshot"); + float actViolent = GetDefAct("dieViolent"); + float actForward = GetDefAct("dieForward"); + float actBackward = GetDefAct("dieBackward"); + float actSimple = GetDefAct("dieSimple"); + float actBackshot = GetDefAct("dieBackshot"); float actDeath = -1; @@ -1710,13 +1729,13 @@ NSMonster::Death(entity inflictor, entity attacker, int damage, vector dir, int switch (g_dmg_iHitBody) { case BODY_HEAD: - actDeath = GetAct("dieHeadshot"); + actDeath = GetDefAct("dieHeadshot"); break; case BODY_CHEST: - actDeath = GetAct("dieChestshot"); + actDeath = GetDefAct("dieChestshot"); break; case BODY_STOMACH: - actDeath = GetAct("dieGutshot"); + actDeath = GetDefAct("dieGutshot"); break; } @@ -1784,27 +1803,18 @@ NSMonster::Spawned(void) if (!owner) { owner = this; } + + flags = FL_MONSTER; } void NSMonster::Respawn(void) { - /* we need to delay the DropToFloor() by at least a frame. - otherwise they may just fall through an entity (func_wall, func_train etc.) - that came after this entity in the lump. */ - static void AdjustSpawnPos(void) { - RestoreAngles(); - m_vecSequenceAngle = GetAngles(); - SetOrigin(GetSpawnVector("origin")); - DropToFloor(); - SetOriginUnstick(origin); - } - super::Respawn(); RestoreAngles(); v_angle = fixAngle(GetAngles()); - flags = FL_MONSTER; + m_vecSequenceAngle = GetAngles(); MakeVulnerable(); EnableAimAssist(); SetState(MONSTER_IDLE); @@ -1812,16 +1822,15 @@ NSMonster::Respawn(void) m_eEnemy = __NULL__; m_iFlags = 0x0; EnableBleeding(); + SetSize(GetSpawnVector("mins"), GetSpawnVector("maxs")); + SetSkin(GetSpawnFloat("skin")); customphysics = Physics; SetSolid(SOLID_SLIDEBOX); SetMovetype(MOVETYPE_WALK); - SetSize(GetSpawnVector("mins"), GetSpawnVector("maxs")); SetEyePos([0, 0, m_flEyeHeight]); - SetSkin(m_flSkin); - - if (CreatedByMap() == true) { - ScheduleThink(AdjustSpawnPos, 0.0f); - } + SetOrigin(GetSpawnVector("origin")); + DropToFloor(); + SetOriginUnstick(origin); if (HasSpawnFlags(MSF_MONSTERCLIP)) { hitcontentsmaski = CONTENTBITS_BOXSOLID | CONTENTBIT_MONSTERCLIP; @@ -1851,6 +1860,8 @@ NSMonster::Respawn(void) m_bGagged = false; } + targetname = GetSpawnString("targetname"); + /* automatically start */ if (STRING_SET(targetname)) { if (HasTriggerTarget() == true) { @@ -2253,7 +2264,7 @@ NSMonster::_RenderDebugViewCone(void) float flDot; vector testOrg; - if (health <= 0 || GetSolid(SOLID_CORPSE)) { + if (health <= 0 || GetSolid() == SOLID_CORPSE) { return; } diff --git a/src/shared/NSNavAI.h b/src/shared/NSNavAI.h index bea3749f..ab83cb36 100644 --- a/src/shared/NSNavAI.h +++ b/src/shared/NSNavAI.h @@ -26,7 +26,7 @@ _NSActor_Log(string className, string functionName, float edictNum, string warnM else printf("^5%s (%d) ^7: %s\n", functionName, edictNum, warnMessage); } -#define NSActor_Log(...) _NSActor_Log(classname, __FUNC__, num_for_edict(this), sprintf(__VA_ARGS__)) +#define NSActor_Log(...) if (autocvar_g_logLevel >= LOGLEVEL_DEBUG) _NSActor_Log(classname, __FUNC__, num_for_edict(this), sprintf(__VA_ARGS__)) /* for AI identification purposes */ typedef enum @@ -68,6 +68,8 @@ public: /** Overridable: Returns the desired maximum backwardss movement speed. */ virtual float GetBackSpeed(void); + nonvirtual float GetStamina(void); + /** Returns `true` when the entity is ducked/crouching */ nonvirtual bool IsCrouching(void); /** Returns `true` when the entity is ducked/crouching */ @@ -190,6 +192,7 @@ private: NSWeapon m_activeWeapon_net; float activeweapon; NETWORKED_FLOAT(m_flFirstInventoryItem) + NETWORKED_FLOAT(m_flStamina) }; /* for now here to make debugging easier */ diff --git a/src/shared/NSNavAI.qc b/src/shared/NSNavAI.qc index 66aa352c..3745fba3 100644 --- a/src/shared/NSNavAI.qc +++ b/src/shared/NSNavAI.qc @@ -35,6 +35,12 @@ NSActor::NSActor(void) } } +float +NSActor::GetStamina(void) +{ + return (m_flStamina / g_pmoveVars.pm_stamina); +} + bool NSActor::IsCrouching(void) { @@ -148,6 +154,7 @@ void NSActor::Spawned(void) { super::Spawned(); + isActor = true; /* let's not waste time and resources */ if (wasfreed(this)) { @@ -170,33 +177,37 @@ NSActor::Spawned(void) string itemList = GetDefString("item"); int desiredWeapon = GetDefInt("current_weapon"); string switchTo = ""; - int weaponCount = tokenizebyseparator(weaponList, ","); + float weaponCount = 0; + + float desiredTeam = GetSpawnFloat("team"); + + if (desiredTeam == 0) + SetTeam(TEAM_UNASSIGNED); + else + SetTeam(desiredTeam); /* append items to the end */ - if (itemList != "") { + if (STRING_SET(itemList)) { weaponList = sprintf("%s,%s", weaponList, itemList); } - for (int i = 0; i < weaponCount; i++) { + for (float i = 0; i < tokenizebyseparator(weaponList, ","); i++) { string itemName = argv(i); GiveItem(itemName); if (i == desiredWeapon) { switchTo = itemName; } - - /* re-calculate because GiveItem may overwrite argv() */ - weaponCount = tokenizebyseparator(weaponList, ","); } - if (switchTo != "") { + if (STRING_SET(switchTo)) { SwitchToWeapon(switchTo); } /* give them their desired appearance */ string spawnModel = GetSpawnString("model"); - if (spawnModel != "") { + if (STRING_SET(spawnModel)) { SetModel(GetSpawnString("model")); } } @@ -216,6 +227,22 @@ void NSActor::Input(entity eAct, string strInput, string strData) { switch (strInput) { + case "UseItem": + if (HasItem(strData)) { + NSItem linkedList; + + linkedList = m_itemList; + + while (linkedList) { + /* inventory item may not be a weapon */ + if (linkedList.classname == strData) { + linkedList.OnUse(eAct); + break; + } + linkedList = (NSItem)linkedList.m_nextItem; + } + } + break; case "GiveItem": GiveItem(strData); break; @@ -245,13 +272,18 @@ NSActor::RouteEnded(void) void NSActor::CheckRoute_Path(void) { - float flDist = floor(vlen(m_pathEntity.GetOrigin() - GetOrigin())); + float flDist = distance(m_pathEntity.GetOrigin(), GetOrigin()); //print(sprintf("Check Path! %f\n", flDist)); /* close enough...? */ if (flDist < 80) { - NSActor_Log("Reached path node %S", m_pathTarget); + + if (targetname) { + NSActor_Log("%S reached path node %S", targetname, m_pathTarget); + } else { + NSActor_Log("Reached path node %S", m_pathTarget); + } m_pathTarget = m_pathEntity.target; m_pathEntity = (NSEntity)m_pathEntity.GetTargetEntity(); @@ -266,7 +298,12 @@ NSActor::CheckRoute(void) float flNodeRadius; vector evenpos; - if (m_pathTarget) { + /* if we're targetting ourselves, we act like a turret */ + if (m_pathTarget == targetname) { + return; + } + + if (STRING_SET(m_pathTarget)) { CheckRoute_Path(); return; } @@ -799,7 +836,7 @@ NSActor::AddedItemCallback(NSItem itemAdded) #ifdef SERVER if (!m_activeWeapon) { if (itemAdded.IsWeapon()) { - SwitchToExactWeapon(itemAdded); + SwitchToExactWeapon((NSWeapon)itemAdded); } } #endif diff --git a/src/shared/NSPhysicsEntity.qc b/src/shared/NSPhysicsEntity.qc index 937f3a9b..aea8ea14 100644 --- a/src/shared/NSPhysicsEntity.qc +++ b/src/shared/NSPhysicsEntity.qc @@ -14,52 +14,42 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/* all the documented phys vars...*/ +.float geomtype; +.float friction; +.float erp; +.float jointtype; +.float mass; +.float bouncefactor; +.float bouncestop; .float max_angular; /* taken from VPhysics-Jolt (with permission!) */ const float InchesToMeters = 0.0254f; const float MetersToInches = 1.0f / 0.0254f; +bool +Physics_Simple(void) +{ + if (time < 5.0f) { + return (true); + } + + return (false); +} + void NSPhysicsEntity::NSPhysicsEntity(void) { mass = 1.0f; isPhysics = true; m_flInertiaScale = 1.0f; - m_iEnabled = 0i; - m_iShape = PHYSM_BOX; + m_iShape = GEOMTYPE_TRIMESH; m_iMaterial = 0i; m_iFlags = 0i; - damp_linear = 1.0f; - damp_angular = 1.0f; - max_angular = -1.0f; m_flMass = 1.0f; - - - cvar_set("physics_ode_quadtree_depth", "5"); - cvar_set("physics_ode_contactsurfacelayer", "0"); - cvar_set("physics_ode_worldquickstep", "1"); - cvar_set("physics_ode_worldquickstep_iterations", "20"); - cvar_set("physics_ode_contact_mu", "1"); - cvar_set("physics_ode_contact_erp", "0.96"); - cvar_set("physics_ode_contact_cfm", "0.001"); - cvar_set("physics_ode_world_damping", "1"); - cvar_set("physics_ode_world_damping_linear", "-1"); - cvar_set("physics_ode_world_damping_linear_threshold", "-1"); - cvar_set("physics_ode_world_damping_angular", "-1"); - cvar_set("physics_ode_world_damping_angular_threshold", "-1"); - cvar_set("physics_ode_world_erp", "-1"); - cvar_set("physics_ode_world_cfm", "-1"); - cvar_set("physics_ode_iterationsperframe", "4"); - cvar_set("physics_ode_movelimit", "0.5"); - cvar_set("physics_ode_spinlimit", "10000"); - cvar_set("physics_ode_autodisable", "1"); - cvar_set("physics_ode_autodisable_steps", "10"); - cvar_set("physics_ode_autodisable_time", "0.1"); - cvar_set("physics_ode_autodisable_threshold_linear", "0.2"); - cvar_set("physics_ode_autodisable_threshold_angular", "0.3"); - cvar_set("physics_ode_autodisable_threshold_samples", "5"); + max_angular = 6500.0f; #ifdef SERVER m_strOnDamaged = __NULL__; @@ -124,14 +114,6 @@ bool physics_supported(void) } #endif -/* all the documented phys vars...*/ -.float geomtype; -.float friction; -.float erp; -.float jointtype; -.float mass; -.float bouncefactor; -.float bouncestop; #ifdef SERVER void @@ -407,12 +389,11 @@ NSPhysicsEntity::CalculateImpactDamage(int iDamage, int dmgType) } int -NSPhysicsEntity_Contents(vector org) +NSPhysicsEntity_Contents(entity target, vector org) { - int oldhitcontents = self.hitcontentsmaski; - self.hitcontentsmaski = -1; - traceline(org, org, MOVE_EVERYTHING, self); - self.hitcontentsmaski = oldhitcontents; + target.hitcontentsmaski = -1; + traceline(org, org, MOVE_EVERYTHING, target); + target.hitcontentsmaski = CONTENTBITS_POINTSOLID; return trace_endcontentsi; } @@ -429,18 +410,24 @@ NSPhysicsEntity::Touch(entity eToucher) return; } - if (IsAsleep() == true) { + if (time < 10.0) { + return; + } + + if (Physics_Simple() == true) { return; } float impactForce = length(GetVelocity()) * 0.01; + //printf("Impact force: %d; required: %d\n", impactForce, GetHealth()); + if (impactForce > GetHealth()) { NSDict damageDecl = spawn(NSDict); damageDecl.AddKey("damage", ftos(impactForce)); Damage(eToucher, eToucher, damageDecl, 1.0f, g_vec_null, GetOrigin()); remove(damageDecl); - printf("New health: %d, impact force: %d\n", health, impactForce); + //printf("New health: %d, impact force: %d\n", health, impactForce); } if (eToucher) @@ -456,7 +443,7 @@ NSPhysicsEntity::_TouchThink(void) return; } - if (physics_supported() == FALSE && GetSolid() != SOLID_TRIGGER) { + if (physics_supported() == FALSE && GetSolid() != SOLID_CORPSE) { EnablePlayerCollision(); tracebox(origin, mins, maxs, origin, FALSE, this); @@ -478,13 +465,13 @@ NSPhysicsEntity::_TouchThink(void) #if 1 if (m_flCheckTime < time) { - bool should - if (vlen(m_vecPrevAngles - angles) < 1) { - avelocity = [0,0,0]; + if (lengthSquared(m_vecPrevAngles - angles) < 4) { + avelocity = g_vec_null; } - if (vlen(m_vecPrevOrigin - origin) < 1) { - velocity = [0,0,0]; + if (lengthSquared(m_vecPrevOrigin - origin) < 4) { + velocity = g_vec_null; } + m_flCheckTime = time + 1.0f; m_vecPrevOrigin = origin; m_vecPrevAngles = angles; @@ -511,33 +498,31 @@ NSPhysicsEntity::_TouchThink(void) } #endif -#if 0 +#if 1 if (m_flBuoyancyRatio > 0.0) - if (NSPhysicsEntity_Contents(origin) & CONTENTBIT_WATER) { - makevectors([0,0,0]); - velocity[2] += m_flBuoyancyRatio; + if (NSPhysicsEntity_Contents(this, origin) & CONTENTBIT_WATER) { + velocity[2] += m_flBuoyancyRatio * frametime; } #endif - hitcontentsmaski &= ~CONTENTBITS_FLUID; - - if (physics_supported() == FALSE && GetSolid() != SOLID_TRIGGER) { + if (physics_supported() == FALSE && GetSolid() != SOLID_CORPSE) { DisablePlayerCollision(); } /* continue testing next frame */ nextthink = time; - effects &= ~EF_NOSHADOW; - solid = SOLID_BSP; } #ifdef SERVER void NSPhysicsEntity::Pain(entity inflictor, entity attacker, int damage, vector dir, int location) { - vector forceDir; float force; + if (modelindex == 0) { + return; + } + if (m_strOnDamaged) { UseOutput(this, m_strOnDamaged); } @@ -566,10 +551,14 @@ NSPhysicsEntity::Pain(entity inflictor, entity attacker, int damage, vector dir, void NSPhysicsEntity::Death(entity inflictor, entity attacker, int damage, vector dir, int location) { + if (modelindex == 0) { + return; + } + Pain(inflictor, attacker, damage, dir, location); super::Death(inflictor, attacker, damage, dir, location); - /* make sure touch think is called */ - nextthink = time; + SetSolid(SOLID_NOT); + ReleaseThink(); } #endif @@ -579,51 +568,45 @@ NSPhysicsEntity::Respawn(void) super::Respawn(); ClearVelocity(); - SetMovetype(MOVETYPE_PHYSICS); - SetSolid(SOLID_BSP); + Sleep(); #ifdef SERVER MakeVulnerable(); #endif - Sleep(); SetMass(1.0f); SetFriction(1.0f); SetBuoyancyRatio(1.0f); - bouncefactor = 0.9f; - bouncestop = 0.1f / cvar("sv_gravity"); - - bouncefactor = 0.0f; - bouncestop = 0.0f; geomtype = GEOMTYPE_BOX; friction = 1.0f; m_flBuoyancyRatio = 1.0f; - SetDamping(1.0f, 1.0f); + SetDamping(0.0f, 0.0f); EnableGravity(true); - hitcontentsmaski &= ~CONTENTBITS_FLUID; + hitcontentsmaski = CONTENTBITS_POINTSOLID; - if (physics_supported() == FALSE && GetSolid() != SOLID_TRIGGER) { + if (physics_supported() == FALSE && GetSolid() != SOLID_CORPSE) { DisablePlayerCollision(); } - think = _TouchThink; - nextthink = time + 0.1f; - - effects &= ~EF_NOSHADOW; + Wake(); #ifdef SERVER if (HasPropData()) { - SetHealth(GetPropData(PROPINFO_HEALTH)); SetMass(GetPropData(PROPINFO_MASS)); SetDamping(GetPropData(PROPINFO_DAMPING_LINEAR), GetPropData(PROPINFO_DAMPING_ANGULAR)); SetInertia(GetPropData(PROPINFO_INERTIA)); SetSurfaceData(GetPropData(PROPINFO_SURFACEPROP)); + } + + + if (HasPropData()) { + SetHealth(GetPropData(PROPINFO_HEALTH)); } else { - health = 0; + health = 1; } /* no health set, either indistructible or too weak */ @@ -634,7 +617,7 @@ NSPhysicsEntity::Respawn(void) health = 10000; } else { /* something like glass bottles, maybe. */ - health = 1.0f; + health = 1; } } #endif @@ -648,7 +631,7 @@ NSPhysicsEntity::SpawnKey(string strKey, string strValue) switch (strKey) { case "physmodel": m_iShape = ReadInt(strValue); - if (m_iShape > PHYSM_CYLINDER) + if (m_iShape > GEOMTYPE_CYLINDER) m_iShape = 0; break; case "massscale": @@ -972,36 +955,58 @@ NSPhysicsEntity::SetMass(float val) void NSPhysicsEntity::Wake(void) { + if (!modelindex) { + return; + } + if (physics_supported() == TRUE) { SetMovetype(MOVETYPE_PHYSICS); SetSolid(SOLID_BSP); /* Don't need a lot of precision during this */ - if (time < 5.0) { + if (Physics_Simple() == true) { geomtype = GEOMTYPE_BOX; + friction = 10000.0f; + //SetDamping(1.0f, 1.0f); } else { - geomtype = GEOMTYPE_TRIMESH; + geomtype = m_iShape; + friction = 1.0f; + //SetDamping(0.0f, 0.0f); } - + physics_enable(this, TRUE); } else { SetMovetype(MOVETYPE_BOUNCE); SetSolid(SOLID_CORPSE); } + + if (isItem(this) == true) { + SetSolid(SOLID_CORPSE); + } + m_iEnabled = TRUE; } void NSPhysicsEntity::Sleep(void) { - if (physics_supported() == TRUE) { - ClearVelocity(); - physics_enable(this, FALSE); - SetMovetype(MOVETYPE_NONE); + if (!modelindex) { + return; + } + + ClearVelocity(); + SetMovetype(MOVETYPE_NONE); + + if (isItem(this) == true) { SetSolid(SOLID_CORPSE); } else { - SetMovetype(MOVETYPE_NONE); SetSolid(SOLID_BBOX); } + + if (physics_supported() == TRUE) { + physics_enable(this, FALSE); + } + + Relink(); m_iEnabled = FALSE; } diff --git a/src/shared/NSPointTrigger.h b/src/shared/NSPointTrigger.h index 3aa1e098..e3eb3e1b 100644 --- a/src/shared/NSPointTrigger.h +++ b/src/shared/NSPointTrigger.h @@ -38,8 +38,5 @@ public: virtual void SpawnKey(string, string); virtual void Save(float); virtual void Restore(string, string); - -private: - string m_strDebugTexture; #endif }; diff --git a/src/shared/NSPointTrigger.qc b/src/shared/NSPointTrigger.qc index c484b054..d22f84a5 100644 --- a/src/shared/NSPointTrigger.qc +++ b/src/shared/NSPointTrigger.qc @@ -17,9 +17,6 @@ void NSPointTrigger::NSPointTrigger(void) { -#ifdef SERVER - m_strDebugTexture = __NULL__; -#endif } void @@ -39,10 +36,6 @@ NSPointTrigger::InitPointTrigger(void) #ifdef SERVER RestoreAngles(); m_bEnabled = (m_bStartDisabled) ? false : true; - - if (m_strDebugTexture == __NULL__) { - m_strDebugTexture = strcat("textures/editor/", classname); - } #endif } @@ -50,13 +43,17 @@ void NSPointTrigger::DebugDraw(void) { #ifdef SERVER + if (!STRING_SET(m_strEditorIcon)) { + return; + } + vector centerPos = WorldSpaceCenter(); super::DebugDraw(); - R_BeginPolygon(m_strDebugTexture, 0, 0); - R_PolygonVertex(centerPos + v_right * 16 - v_up * 16, [1,1], [1,1,1], 1.0f); - R_PolygonVertex(centerPos - v_right * 16 - v_up * 16, [0,1], [1,1,1], 1.0f); - R_PolygonVertex(centerPos - v_right * 16 + v_up * 16, [0,0], [1,1,1], 1.0f); - R_PolygonVertex(centerPos + v_right * 16 + v_up * 16, [1,0], [1,1,1], 1.0f); + R_BeginPolygon(m_strEditorIcon, 0, 0); + R_PolygonVertex(centerPos + v_right * 8 - v_up * 8, [1,1], [1,1,1], 1.0f); + R_PolygonVertex(centerPos - v_right * 8 - v_up * 8, [0,1], [1,1,1], 1.0f); + R_PolygonVertex(centerPos - v_right * 8 + v_up * 8, [0,0], [1,1,1], 1.0f); + R_PolygonVertex(centerPos + v_right * 8 + v_up * 8, [1,0], [1,1,1], 1.0f); R_EndPolygon(); #endif } @@ -67,9 +64,6 @@ void NSPointTrigger::SpawnKey(string strKey, string strValue) { switch (strKey) { - case "editor_sprite": - m_strDebugTexture = ReadString(strValue); - break; default: super::SpawnKey(strKey, strValue); break; @@ -80,16 +74,12 @@ void NSPointTrigger::Save(float handle) { super::Save(handle); - SaveString(handle, "m_strDebugTexture", m_strDebugTexture); } void NSPointTrigger::Restore(string strKey, string strValue) { switch (strKey) { - case "m_strDebugTexture": - m_strDebugTexture = ReadString(strValue); - break; default: super::Restore(strKey, strValue); break; diff --git a/src/shared/NSProjectile.h b/src/shared/NSProjectile.h index b7e239dd..4648a812 100644 --- a/src/shared/NSProjectile.h +++ b/src/shared/NSProjectile.h @@ -52,6 +52,7 @@ public: #ifdef CLIENT virtual void ReceiveEntity(float, float); virtual float predraw(void); + virtual void postdraw(void); #endif #ifdef SERVER @@ -179,6 +180,7 @@ private: bool m_bStickToActor; bool m_bThrustHoming; bool m_bInheritVelocity; + bool m_bReflect; NSTimer m_thrustHandler; diff --git a/src/shared/NSProjectile.qc b/src/shared/NSProjectile.qc index 65949516..7b9c86d1 100644 --- a/src/shared/NSProjectile.qc +++ b/src/shared/NSProjectile.qc @@ -283,6 +283,9 @@ NSProjectile::SpawnKey(string strKey, string strValue) case "thrown": m_bThrown = ReadBool(strValue); break; + case "reflects": + m_bReflect = ReadBool(strValue); + break; default: super::SpawnKey(strKey, strValue); break; @@ -522,11 +525,25 @@ NSProjectile::Spawned(void) SetSize(m_vecSpawnMins, m_vecSpawnMaxs); } + + void NSProjectile::Touch(entity eToucher) { m_vecImpactPos = trace_endpos; + if (eToucher == world && m_bReflect) { + vector currentAngle = GetAngles(); + currentAngle[0] *= -1; + vector currentVelocity = anglesToForward(currentAngle); + SetMovetype(MOVETYPE_FLYMISSILE); + SetVelocity(reflect(currentVelocity, trace_plane_normal) * m_vecLaunchVelocity[0]); + SetAngles(vectoangles(GetVelocity())); + SetOrigin(GetOrigin() + (anglesToForward(GetAngles() * 2.0f))); + StartSoundDef(m_sndBounce, CHAN_BODY, true); + return; + } + if (eToucher.takedamage != DAMAGE_NO) { NSSurfacePropEntity toucher = (NSSurfacePropEntity)eToucher; NSDict damageDecl = spawn(NSDict); @@ -780,7 +797,7 @@ NSProjectile::_Explode(entity explodedOn) flDamage *= m_flDmgMultiplier; } - radiusDamage(damagePos, flRadius, (int)flMinDamage, (int)flDamage, owner, m_defSplashDamage); + combat.RadiusDamage(damagePos, flRadius, (int)flMinDamage, (int)flDamage, owner, m_defSplashDamage); } /* another def that'll be spawned when this one detonates */ @@ -788,7 +805,7 @@ NSProjectile::_Explode(entity explodedOn) float movementAmount = 360.0f / (float)m_iDebrisCount; for (int i = 0; i < m_iDebrisCount; i++) { - NSProjectile_SpawnDefAtPosition(m_defProjectileDebris, (NSEntity)owner, debrisPos, debrisAngle); + NSProjectile_SpawnDefAtPosition(m_defProjectileDebris, (NSActor)owner, debrisPos, debrisAngle); debrisAngle[1] += movementAmount; } } @@ -849,9 +866,9 @@ NSProjectile::_ApplyDamage(void) damageDecl.AddKey("hitbody", itos(trace_surface_id)); damageDecl.AddKey("damage", itos(m_iMultiValue)); - vector dmgDir = normalize(angles); - - entityDamage(m_eMultiTarget, owner, owner, damageDecl.GetDeclBody(), GetWeaponOwner().classname, GetOrigin(), dmgDir, trace_endpos); + damageDecl.AddKey("weapon", GetWeaponOwner().classname); + vector dmgDir = anglesToForward(angles); + m_eMultiTarget.Damage(this, owner, damageDecl, m_flDmgMultiplier, vectorNormalize(angles), m_vecImpactPos); remove(damageDecl); m_eMultiTarget = __NULL__; @@ -979,7 +996,7 @@ NSProjectile::_ThrustThink(void) newVelocity = v_forward * (newSpeed); /* prevent thrusting early */ - if ((m_flThrustStart > 0) && GetSpawnAge() < m_flThrustStart) { + if ((m_flThrustStart > 0) && GetSpawnAge() < m_flThrustStart) { return; } @@ -1005,11 +1022,13 @@ NSProjectile::Launch(vector startPos, vector launchDir, float fuseOffset, float SetAngles(launchDir); SetSize(m_vecSpawnMins, m_vecSpawnMaxs); - if (dmgMultiplier <= 0.0) + if (dmgMultiplier <= 0.0) { dmgMultiplier = 1.0f; + } - if (powerMultiplier <= 0.0) + if (powerMultiplier <= 0.0) { powerMultiplier = 1.0f; + } m_flDmgMultiplier = dmgMultiplier; @@ -1083,7 +1102,14 @@ NSProjectile::Launch(vector startPos, vector launchDir, float fuseOffset, float MakeInvulnerable(); } - if (m_flFuse > 0) { + if (m_flFuse > 0.0f) { + /* quit early */ + if ((m_flFuse - fuseOffset)<= 0.0f) { + m_vecImpactPos = startPos; + _Explode(owner); + return; + } + ScheduleThink(_FuseEnded, m_flFuse - fuseOffset); } @@ -1209,6 +1235,16 @@ NSProjectile::ReceiveEntity(float flNew, float flChanged) drawmask = MASK_ENGINE; } +void +NSProjectile::postdraw(void) +{ +#if 1 + if (m_flLightRadius > 0.0) { + env_sun_lensflare(origin, 1.0f, m_vecLightColor, false); + } +#endif +} + float NSProjectile::predraw(void) { diff --git a/src/shared/NSRagdoll.h b/src/shared/NSRagdoll.h new file mode 100644 index 00000000..65790dd9 --- /dev/null +++ b/src/shared/NSRagdoll.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016-2022 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +/** Ragdoll master entity. + +@ingroup baseclass +*/ +class NSRagdoll:NSRenderableEntity +{ +public: + void NSRagdoll(void); + +#ifdef SERVER + virtual void EvaluateEntity(void); + virtual float SendEntity(entity,float); +#endif + +#ifdef CLIENT + virtual void ReceiveEntity(float,float); + virtual float predraw(void); +#endif + + +private: + float m_skelRagdoll; +}; + + +#ifdef CLIENT +void NSRagdoll_Create(string modelFile); +#endif diff --git a/src/shared/NSRagdoll.qc b/src/shared/NSRagdoll.qc new file mode 100644 index 00000000..c250bad4 --- /dev/null +++ b/src/shared/NSRagdoll.qc @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2016-2024 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +void +NSRagdoll::NSRagdoll(void) +{ + m_skelRagdoll = 0; +} + +#ifdef SERVER +void +NSRagdoll::EvaluateEntity(void) +{ + EVALUATE_VECTOR(origin, 0, RDENT_CHANGED_ORIGIN_X) + EVALUATE_VECTOR(origin, 1, RDENT_CHANGED_ORIGIN_Y) + EVALUATE_VECTOR(origin, 2, RDENT_CHANGED_ORIGIN_Z) + EVALUATE_VECTOR(angles, 0, RDENT_CHANGED_ANGLES_X) + EVALUATE_VECTOR(angles, 1, RDENT_CHANGED_ANGLES_Y) + EVALUATE_VECTOR(angles, 2, RDENT_CHANGED_ANGLES_Z) + EVALUATE_FIELD(modelindex, RDENT_CHANGED_MODELINDEX) + EVALUATE_FIELD(colormap, RDENT_CHANGED_MODELINDEX) + EVALUATE_FIELD(solid, RDENT_CHANGED_SOLIDMOVETYPE) + EVALUATE_FIELD(movetype, RDENT_CHANGED_SOLIDMOVETYPE) + EVALUATE_FIELD(flags, RDENT_CHANGED_FLAGS) + EVALUATE_FIELD(modelflags, RDENT_CHANGED_FLAGS) + EVALUATE_VECTOR(mins, 0, RDENT_CHANGED_SIZE) + EVALUATE_VECTOR(mins, 1, RDENT_CHANGED_SIZE) + EVALUATE_VECTOR(mins, 2, RDENT_CHANGED_SIZE) + EVALUATE_VECTOR(maxs, 0, RDENT_CHANGED_SIZE) + EVALUATE_VECTOR(maxs, 1, RDENT_CHANGED_SIZE) + EVALUATE_VECTOR(maxs, 2, RDENT_CHANGED_SIZE) + EVALUATE_FIELD(frame, RDENT_CHANGED_FRAME) + EVALUATE_FIELD(frame1time, RDENT_CHANGED_FRAME) + EVALUATE_FIELD(skin, RDENT_CHANGED_SKIN) + EVALUATE_FIELD(effects, RDENT_CHANGED_EFFECTS) + EVALUATE_FIELD(m_iBody, RDENT_CHANGED_BODY) + EVALUATE_FIELD(scale, RDENT_CHANGED_SCALE) + EVALUATE_VECTOR(m_vecAxialScale, 0, RDENT_CHANGED_SCALE) + EVALUATE_VECTOR(m_vecAxialScale, 1, RDENT_CHANGED_SCALE) + EVALUATE_VECTOR(m_vecAxialScale, 2, RDENT_CHANGED_SCALE) + EVALUATE_VECTOR(velocity, 0, RDENT_CHANGED_VELOCITY) + EVALUATE_VECTOR(velocity, 1, RDENT_CHANGED_VELOCITY) + EVALUATE_VECTOR(velocity, 2, RDENT_CHANGED_VELOCITY) + EVALUATE_VECTOR(avelocity, 0, RDENT_CHANGED_ANGULARVELOCITY) + EVALUATE_VECTOR(avelocity, 1, RDENT_CHANGED_ANGULARVELOCITY) + EVALUATE_VECTOR(avelocity, 2, RDENT_CHANGED_ANGULARVELOCITY) + EVALUATE_FIELD(m_iRenderMode, RDENT_CHANGED_RENDERMODE) + EVALUATE_FIELD(m_iRenderFX, RDENT_CHANGED_RENDERMODE) + EVALUATE_VECTOR(m_vecRenderColor, 0, RDENT_CHANGED_RENDERCOLOR) + EVALUATE_VECTOR(m_vecRenderColor, 1, RDENT_CHANGED_RENDERCOLOR) + EVALUATE_VECTOR(m_vecRenderColor, 2, RDENT_CHANGED_RENDERCOLOR) + EVALUATE_VECTOR(glowmod, 0, RDENT_CHANGED_RENDERCOLOR) + EVALUATE_VECTOR(glowmod, 1, RDENT_CHANGED_RENDERCOLOR) + EVALUATE_VECTOR(glowmod, 2, RDENT_CHANGED_RENDERCOLOR) + EVALUATE_FIELD(m_flRenderAmt, RDENT_CHANGED_RENDERAMT) + EVALUATE_FIELD(m_flBoneControl1, RDENT_CHANGED_CONTROLLER) + EVALUATE_FIELD(m_flBoneControl2, RDENT_CHANGED_CONTROLLER) + EVALUATE_FIELD(m_flBoneControl3, RDENT_CHANGED_CONTROLLER) + EVALUATE_FIELD(m_flBoneControl4, RDENT_CHANGED_CONTROLLER) + EVALUATE_FIELD(m_flBoneControl5, RDENT_CHANGED_CONTROLLER) +} + +/* Make sure StartFrame calls this */ +float +NSRagdoll::SendEntity(entity ePEnt, float flChanged) +{ + if (!modelindex && solid == SOLID_NOT) + return (0); + + WriteByte(MSG_ENTITY, ENT_RAGDOLL); + + /* optimisation */ + { + /* we'll never network these if we aren't moving. */ + if (movetype == MOVETYPE_NONE) { + flChanged &= ~RDENT_CHANGED_VELOCITY; + flChanged &= ~RDENT_CHANGED_ANGULARVELOCITY; + } + + /* no rendermode means no extra fields */ + if (m_iRenderMode == RM_NORMAL && m_iRenderFX == RFX_NORMAL) { + flChanged &= ~RDENT_CHANGED_RENDERMODE; + //flChanged &= ~RDENT_CHANGED_RENDERCOLOR; /* glowmod needs this */ + flChanged &= ~RDENT_CHANGED_RENDERAMT; + } + + if (m_bIsBrush == true) { + flChanged &= ~RDENT_CHANGED_FLAGS; + flChanged &= ~RDENT_CHANGED_BODY; + flChanged &= ~RDENT_CHANGED_SCALE; + flChanged &= ~RDENT_CHANGED_CONTROLLER; + } + } + + /* broadcast how much data is expected to be read */ + WriteFloat(MSG_ENTITY, flChanged); + + SENDENTITY_COORD(origin[0], RDENT_CHANGED_ORIGIN_X) + SENDENTITY_COORD(origin[1], RDENT_CHANGED_ORIGIN_Y) + SENDENTITY_COORD(origin[2], RDENT_CHANGED_ORIGIN_Z) + SENDENTITY_ANGLE(angles[0], RDENT_CHANGED_ANGLES_X) + SENDENTITY_ANGLE(angles[1], RDENT_CHANGED_ANGLES_Y) + SENDENTITY_ANGLE(angles[2], RDENT_CHANGED_ANGLES_Z) + SENDENTITY_SHORT(modelindex, RDENT_CHANGED_MODELINDEX) + SENDENTITY_BYTE(colormap, RDENT_CHANGED_MODELINDEX) + SENDENTITY_BYTE(solid, RDENT_CHANGED_SOLIDMOVETYPE) + SENDENTITY_BYTE(movetype, RDENT_CHANGED_SOLIDMOVETYPE) + SENDENTITY_INT(flags, RDENT_CHANGED_FLAGS) + SENDENTITY_INT(modelflags, RDENT_CHANGED_FLAGS) + SENDENTITY_COORD(mins[0], RDENT_CHANGED_SIZE) + SENDENTITY_COORD(mins[1], RDENT_CHANGED_SIZE) + SENDENTITY_COORD(mins[2], RDENT_CHANGED_SIZE) + SENDENTITY_COORD(maxs[0], RDENT_CHANGED_SIZE) + SENDENTITY_COORD(maxs[1], RDENT_CHANGED_SIZE) + SENDENTITY_COORD(maxs[2], RDENT_CHANGED_SIZE) + SENDENTITY_FLOAT(frame, RDENT_CHANGED_FRAME) + SENDENTITY_FLOAT(frame1time, RDENT_CHANGED_FRAME) + SENDENTITY_FLOAT(skin, RDENT_CHANGED_SKIN) + SENDENTITY_FLOAT(effects, RDENT_CHANGED_EFFECTS) + SENDENTITY_SHORT(m_iBody, RDENT_CHANGED_BODY) + SENDENTITY_FLOAT(scale, RDENT_CHANGED_SCALE) + SENDENTITY_FLOAT(m_vecAxialScale[0], RDENT_CHANGED_SCALE) + SENDENTITY_FLOAT(m_vecAxialScale[1], RDENT_CHANGED_SCALE) + SENDENTITY_FLOAT(m_vecAxialScale[2], RDENT_CHANGED_SCALE) + SENDENTITY_COORD(velocity[0], RDENT_CHANGED_VELOCITY) + SENDENTITY_COORD(velocity[1], RDENT_CHANGED_VELOCITY) + SENDENTITY_COORD(velocity[2], RDENT_CHANGED_VELOCITY) + SENDENTITY_COORD(avelocity[0], RDENT_CHANGED_ANGULARVELOCITY) + SENDENTITY_COORD(avelocity[1], RDENT_CHANGED_ANGULARVELOCITY) + SENDENTITY_COORD(avelocity[2], RDENT_CHANGED_ANGULARVELOCITY) + SENDENTITY_BYTE(m_iRenderMode, RDENT_CHANGED_RENDERMODE) + SENDENTITY_BYTE(m_iRenderFX, RDENT_CHANGED_RENDERMODE) + SENDENTITY_COLOR(m_vecRenderColor[0], RDENT_CHANGED_RENDERCOLOR) + SENDENTITY_COLOR(m_vecRenderColor[1], RDENT_CHANGED_RENDERCOLOR) + SENDENTITY_COLOR(m_vecRenderColor[2], RDENT_CHANGED_RENDERCOLOR) + /* these need more precision for shader hacks... */ + SENDENTITY_FLOAT(glowmod[0], RDENT_CHANGED_RENDERCOLOR) + SENDENTITY_FLOAT(glowmod[1], RDENT_CHANGED_RENDERCOLOR) + SENDENTITY_FLOAT(glowmod[2], RDENT_CHANGED_RENDERCOLOR) + SENDENTITY_ANGLE(m_flRenderAmt, RDENT_CHANGED_RENDERAMT) + SENDENTITY_ANGLE(m_flBoneControl1, RDENT_CHANGED_CONTROLLER) + SENDENTITY_ANGLE(m_flBoneControl2, RDENT_CHANGED_CONTROLLER) + SENDENTITY_ANGLE(m_flBoneControl3, RDENT_CHANGED_CONTROLLER) + SENDENTITY_ANGLE(m_flBoneControl4, RDENT_CHANGED_CONTROLLER) + SENDENTITY_ANGLE(m_flBoneControl5, RDENT_CHANGED_CONTROLLER) + + return (1); +} +#else +/* +============ +NSRagdoll::ReceiveEntity +============ +*/ +void +NSRagdoll::ReceiveEntity(float flNew, float flChanged) +{ + READENTITY_COORD(origin[0], RDENT_CHANGED_ORIGIN_X) + READENTITY_COORD(origin[1], RDENT_CHANGED_ORIGIN_Y) + READENTITY_COORD(origin[2], RDENT_CHANGED_ORIGIN_Z) + READENTITY_ANGLE(angles[0], RDENT_CHANGED_ANGLES_X) + READENTITY_ANGLE(angles[1], RDENT_CHANGED_ANGLES_Y) + READENTITY_ANGLE(angles[2], RDENT_CHANGED_ANGLES_Z) + READENTITY_SHORT(modelindex, RDENT_CHANGED_MODELINDEX) + READENTITY_BYTE(colormap, RDENT_CHANGED_MODELINDEX) + READENTITY_BYTE(solid, RDENT_CHANGED_SOLIDMOVETYPE) + READENTITY_BYTE(movetype, RDENT_CHANGED_SOLIDMOVETYPE) + READENTITY_INT(flags, RDENT_CHANGED_FLAGS) + READENTITY_INT(modelflags, RDENT_CHANGED_FLAGS) + READENTITY_COORD(mins[0], RDENT_CHANGED_SIZE) + READENTITY_COORD(mins[1], RDENT_CHANGED_SIZE) + READENTITY_COORD(mins[2], RDENT_CHANGED_SIZE) + READENTITY_COORD(maxs[0], RDENT_CHANGED_SIZE) + READENTITY_COORD(maxs[1], RDENT_CHANGED_SIZE) + READENTITY_COORD(maxs[2], RDENT_CHANGED_SIZE) + READENTITY_FLOAT(frame, RDENT_CHANGED_FRAME) + READENTITY_FLOAT(frame1time, RDENT_CHANGED_FRAME) + READENTITY_FLOAT(skin, RDENT_CHANGED_SKIN) + READENTITY_FLOAT(effects, RDENT_CHANGED_EFFECTS) + READENTITY_SHORT(m_iBody, RDENT_CHANGED_BODY) + READENTITY_FLOAT(scale, RDENT_CHANGED_SCALE) + READENTITY_FLOAT(m_vecAxialScale[0], RDENT_CHANGED_SCALE) + READENTITY_FLOAT(m_vecAxialScale[1], RDENT_CHANGED_SCALE) + READENTITY_FLOAT(m_vecAxialScale[2], RDENT_CHANGED_SCALE) + READENTITY_COORD(velocity[0], RDENT_CHANGED_VELOCITY) + READENTITY_COORD(velocity[1], RDENT_CHANGED_VELOCITY) + READENTITY_COORD(velocity[2], RDENT_CHANGED_VELOCITY) + READENTITY_COORD(avelocity[0], RDENT_CHANGED_ANGULARVELOCITY) + READENTITY_COORD(avelocity[1], RDENT_CHANGED_ANGULARVELOCITY) + READENTITY_COORD(avelocity[2], RDENT_CHANGED_ANGULARVELOCITY) + READENTITY_BYTE(m_iRenderMode, RDENT_CHANGED_RENDERMODE) + READENTITY_BYTE(m_iRenderFX, RDENT_CHANGED_RENDERMODE) + READENTITY_COLOR(m_vecRenderColor[0], RDENT_CHANGED_RENDERCOLOR) + READENTITY_COLOR(m_vecRenderColor[1], RDENT_CHANGED_RENDERCOLOR) + READENTITY_COLOR(m_vecRenderColor[2], RDENT_CHANGED_RENDERCOLOR) + /* these need more precision for shader hacks... */ + READENTITY_FLOAT(glowmod[0], RDENT_CHANGED_RENDERCOLOR) + READENTITY_FLOAT(glowmod[1], RDENT_CHANGED_RENDERCOLOR) + READENTITY_FLOAT(glowmod[2], RDENT_CHANGED_RENDERCOLOR) + READENTITY_ANGLE(m_flRenderAmt, RDENT_CHANGED_RENDERAMT) + READENTITY_ANGLE(m_flBoneControl1, RDENT_CHANGED_CONTROLLER) + READENTITY_ANGLE(m_flBoneControl2, RDENT_CHANGED_CONTROLLER) + READENTITY_ANGLE(m_flBoneControl3, RDENT_CHANGED_CONTROLLER) + READENTITY_ANGLE(m_flBoneControl4, RDENT_CHANGED_CONTROLLER) + READENTITY_ANGLE(m_flBoneControl5, RDENT_CHANGED_CONTROLLER) + + movetype = MOVETYPE_PHYSICS; + + if (!skeletonindex && modelindex) { + skeletonindex = skel_create(modelindex); + skel_build(skeletonindex, this, modelindex, 0, 0, 0, 1); + skel_ragupdate(this, "doll models/rt2/human.doll", 0); + skel_ragupdate(this, "animate 0", 0); + } + + if (scale == 0.0) + scale = 1.0f; + + if (flChanged & RDENT_CHANGED_SIZE) + setsize(this, mins * scale, maxs * scale); + if (flChanged & RDENT_CHANGED_BODY) + _UpdateGeomset(); + if (flChanged & RDENT_CHANGED_MODELINDEX) + _UpdateBoneCount(); +} + +float +NSRagdoll::predraw(void) +{ + if (!modelindex || !skeletonindex) { + return (PREDRAW_NEXT); + } + + frame1time = time; + frame2time = time; + frame = 0; + frame2 = 1; + lerpfrac = 0.0; + skel_build(this.skeletonindex, this, this.modelindex, 0, 0, 0, 1); + skel_ragupdate(this, "", 0); + addentity(this); + return (PREDRAW_NEXT); +} + +void +NSRagdoll_Create(string modelFile) +{ + NSRagdoll rag = spawn(NSRagdoll); + rag.Spawn(); + rag.movetype = MOVETYPE_PHYSICS; + rag.drawmask = MASK_ENGINE; + rag.SetOrigin(g_view.GetCameraOrigin()); + rag.SetModel("models/humans/group03/male_07.mdl"); + + rag.skeletonindex = skel_create(rag.modelindex); + skel_build(rag.skeletonindex, rag, rag.modelindex, 0, 0, 0, 1); + skel_ragupdate(rag, "doll models/rt2/human.doll", 0); + skel_ragupdate(rag, "animate 0", 0); +} +#endif diff --git a/src/shared/NSRenderableEntity.qc b/src/shared/NSRenderableEntity.qc index 5d24729d..99c11180 100644 --- a/src/shared/NSRenderableEntity.qc +++ b/src/shared/NSRenderableEntity.qc @@ -482,10 +482,10 @@ NSRenderableEntity::RenderFXPass(void) case RFX_GLOWSHELL2: /* make this entity shellchrome */ effects = EF_ADDITIVE; - fatness = 0; + fatness = m_flRenderAmt / 25.5; colormod = (m_vecRenderColor / 255); forceshader = g_shellchromeshader_cull; - alpha = (m_flRenderAmt / 255); + alpha = 1.0f; /* copy entity into rendering queue */ addentity(this); /* reset */ @@ -498,10 +498,10 @@ NSRenderableEntity::RenderFXPass(void) case RFX_GLOWSHELL: /* make this entity shellchrome */ effects = EF_ADDITIVE; - fatness = 0; + fatness = m_flRenderAmt / 25.5; colormod = (m_vecRenderColor / 255); forceshader = g_shellchromeshader; - alpha = (m_flRenderAmt / 255); + alpha = 1.0f; /* copy entity into rendering queue */ addentity(this); /* reset */ @@ -621,6 +621,7 @@ NSRenderableEntity::predraw(void) RenderFXPass(); RenderDebugSkeleton(); + if (modelflags & MF_ROTATE) { angles[1] = g_modelSpinAngle; angles[2] = g_modelSpinRoll; @@ -789,17 +790,14 @@ NSRenderableEntity::Respawn(void) SetRenderAmt(GetSpawnFloat("renderamt")); SetRenderColor(GetSpawnVector("rendercolor")); + SetScale(GetSpawnFloat("modelscale")); + SetSkin(GetSpawnInt("skin")); SetBody(GetSpawnInt("body")); SetBodyInGroup(0, GetSpawnInt("body0")); SetBodyInGroup(1, GetSpawnInt("body1")); SetBodyInGroup(2, GetSpawnInt("body2")); SetBodyInGroup(3, GetSpawnInt("body3")); - - //SetRenderFX(GetSpawnRenderFX()); - //SetRenderMode(GetSpawnRenderMode()); - //SetRenderAmt(GetSpawnRenderAmt()); - //SetRenderColor(GetSpawnRenderColor()); } #endif @@ -1224,8 +1222,10 @@ NSRenderableEntity::SpawnKey(string strKey, string strValue) } } +#if 0 float NSRenderableEntity::PlayActOnChannel(float animChannel, string activityName) { - + } +#endif diff --git a/src/shared/NSSound.h b/src/shared/NSSound.h index 2937c13e..a9982adb 100644 --- a/src/shared/NSSound.h +++ b/src/shared/NSSound.h @@ -14,77 +14,56 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -class NSSound:NSPointTrigger { +enumflags +{ + SOUND_SAMPLE, + SOUND_VOLUME, + SOUND_RADIUS, + SOUND_PITCH, + SOUND_ORIGIN, + SOUND_ENABLED +}; + +class +NSSound:NSPointTrigger +{ public: void NSSound( void ); nonvirtual void SetSample( string ); nonvirtual void SetVolume( float ); nonvirtual void SetRadius( float ); + nonvirtual void SetPitch( float ); nonvirtual void SetSoundOffset( float ); nonvirtual void MakeOmniDirectional( void ); nonvirtual void MakeDirectional( void ); nonvirtual void EnableReverb( void ); nonvirtual void DisableReverb( void ); - nonvirtual virtual void Play( void ); + nonvirtual void ForceLoop( bool ); + nonvirtual void Play( void ); + + virtual void Spawned(void); + virtual void OnRemoveEntity(void); + +#ifdef SERVER + virtual void Respawn(void); + virtual void EvaluateEntity(void); + virtual float SendEntity(entity, float); +#endif + +#ifdef CLIENT + virtual void ReceiveEntity(float,float); +#endif private: - float m_radius; - float m_volume; + NETWORKED_FLOAT(m_radius) + NETWORKED_FLOAT(m_volume) + NETWORKED_FLOAT(m_soundIndex) + NETWORKED_FLOAT(m_pitch) + NETWORKED_BOOL(m_isLooping) string m_sample; bool m_omniDirectional; float m_offset; + bool m_ignoreReverb; + bool m_forceLoop; }; - -void NSSound::NSSound( void ) { - m_radius = 128.0f; - m_volume = 0.5f; - m_sample = "common/null.wav"; -} - -void NSSound::SetSample( string newSample ) { - m_sample = newSample; -} - -void NSSound::SetVolume( float newVolume ) { - m_volume = newVolume; -} - -void NSSound::SetRadius( float newRadius ) { - m_radius = newRadius; -} - -void NSSound::SetSoundOffset( float newRadius ) { - m_offset = newRadius; -} - -void NSSound::MakeOmniDirectional( void ) { - m_omniDirectional = true; -} - -void NSSound::MakeDirectional( void ) { - m_omniDirectional = false; -} - -void NSSound::EnableReverb( void ) { - m_ignoreReverb = false; -} - -void NSSound::DisableReverb( void ) { - m_ignoreReverb = true; -} - -void NSSound::Play( void ) { - float soundFlags = 0; - - if ( m_ignoreReverb ) { - soundFlags |= SOUNDFLAG_NOREVERB; - } -#ifdef CLIENT - if ( m_omniDirectional ) { - soundFlags |= SOUNDFLAG_NOSPACIALISE; - } -#endif - - sound( this, CHAN_AUTO, m_sample, m_volume, m_radius, m_pitch, soundFlags, m_offset ); -} diff --git a/src/shared/NSSound.qc b/src/shared/NSSound.qc index e69de29b..d5a3593b 100644 --- a/src/shared/NSSound.qc +++ b/src/shared/NSSound.qc @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2024 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + + +void +NSSound::NSSound( void ) +{ + m_radius = 128.0f; + m_volume = 0.5f; + m_sample = "common/null.wav"; + m_soundIndex = 0; + m_offset = 0.0f; + m_pitch = 100.0f; + m_omniDirectional = false; + m_ignoreReverb = false; + m_forceLoop = true; +} + +void +NSSound::Spawned( void ) +{ + super::Spawned(); + m_soundIndex = getsoundindex(m_sample, false); + +#ifdef SERVER + pvsflags = PVSF_USEPHS; +#endif +} + +void +NSSound::SetSample( string newSample ) +{ + m_sample = newSample; + m_soundIndex = getsoundindex(m_sample, true); +} + +void +NSSound::SetVolume( float newVolume ) +{ + m_volume = newVolume; +} + +void +NSSound::SetPitch( float newPitch ) +{ + m_pitch = newPitch; +} + +void +NSSound::SetRadius( float newRadius ) +{ + m_radius = newRadius; +} + +void +NSSound::SetSoundOffset( float newOffset ) +{ + m_offset = newOffset; +} + +void +NSSound::MakeOmniDirectional( void ) +{ + m_omniDirectional = true; +} + +void +NSSound::MakeDirectional( void ) +{ + m_omniDirectional = false; +} + +void +NSSound::EnableReverb( void ) +{ + m_ignoreReverb = false; +} + +void +NSSound::DisableReverb( void ) +{ + m_ignoreReverb = true; +} + +void +NSSound::ForceLoop( bool forceLooping ) +{ + m_forceLoop = forceLooping; + +#ifdef SERVER + if (m_forceLoop) { + m_isLooping = true; + } else { + m_isLooping = false; + } + SendFlags |= SOUND_ENABLED; +#endif +} + +void +NSSound::Play( void ) +{ + float soundFlags = 0; + + if ( m_ignoreReverb ) { + soundFlags |= SOUNDFLAG_NOREVERB; + } +#ifdef CLIENT + if ( m_omniDirectional ) { + soundFlags |= SOUNDFLAG_NOSPACIALISE; + } +#endif + + sound(this, CHAN_BODY, m_sample, m_volume, (cvar("s_nominaldistance") / m_radius), m_pitch, soundFlags, m_offset); +} + +#ifdef SERVER +void +NSSound::Respawn(void) +{ + super::Respawn(); +} + +void +NSSound::EvaluateEntity(void) +{ + EVALUATE_VECTOR(origin, 0, RDENT_CHANGED_ORIGIN_X) + EVALUATE_VECTOR(origin, 1, RDENT_CHANGED_ORIGIN_Y) + EVALUATE_VECTOR(origin, 2, RDENT_CHANGED_ORIGIN_Z) + EVALUATE_FIELD(m_soundIndex, SOUND_SAMPLE) + EVALUATE_FIELD(m_volume, SOUND_VOLUME) + EVALUATE_FIELD(m_radius, SOUND_RADIUS) + EVALUATE_FIELD(m_pitch, SOUND_PITCH) + EVALUATE_FIELD(m_isLooping, SOUND_ENABLED) +} + +float +NSSound::SendEntity(entity ePEnt, float flChanged) +{ + if (distance(ePEnt.origin, origin) >= m_radius) { + return (false); + } + + WriteByte(MSG_ENTITY, ENT_SOUND); + WriteFloat(MSG_ENTITY, flChanged); + + SENDENTITY_COORD(origin[0], SOUND_ORIGIN) + SENDENTITY_COORD(origin[1], SOUND_ORIGIN) + SENDENTITY_COORD(origin[2], SOUND_ORIGIN) + SENDENTITY_FLOAT(m_soundIndex, SOUND_SAMPLE) + SENDENTITY_FLOAT(m_volume, SOUND_VOLUME) + SENDENTITY_FLOAT(m_radius, SOUND_RADIUS) + SENDENTITY_FLOAT(m_pitch, SOUND_PITCH) + SENDENTITY_BYTE(m_isLooping, SOUND_ENABLED) + + return (true); +} +#endif + +#ifdef CLIENT +void +NSSound::ReceiveEntity(float isnew, float flChanged) +{ + READENTITY_COORD(origin[0], SOUND_ORIGIN) + READENTITY_COORD(origin[1], SOUND_ORIGIN) + READENTITY_COORD(origin[2], SOUND_ORIGIN) + READENTITY_FLOAT(m_soundIndex, SOUND_SAMPLE) + READENTITY_FLOAT(m_volume, SOUND_VOLUME) + READENTITY_FLOAT(m_radius, SOUND_RADIUS) + READENTITY_FLOAT(m_pitch, SOUND_PITCH) + READENTITY_BYTE(m_isLooping, SOUND_ENABLED) + + if (flChanged & SOUND_ORIGIN) { + SetSolid(SOLID_NOT); + SetSize([0,0,0], [0,0,0]); + Relink(); + } + + if (flChanged & SOUND_SAMPLE) { + m_sample = soundnameforindex(m_soundIndex); + } + + if (m_isLooping) + SndEntLog("^2start ^7%S Volume: %d%%; Radius: %d units; Pitch: %d, Org: %v", m_sample, m_volume * 100, m_radius, m_pitch, origin); + else + SndEntLog("^1stop: ^7%S Volume: %d%%; Radius: %d units; Pitch: %d, Org: %v", m_sample, m_volume * 100, m_radius, m_pitch, origin); + + if (flChanged & SOUND_ENABLED) + if (m_isLooping == true) { + soundupdate(this, CHAN_BODY, m_sample, m_volume, (cvar("s_nominaldistance") / m_radius), m_pitch, SOUNDFLAG_FORCELOOP, 0); + } else { + OnRemoveEntity(); + } +} +#endif + +void +NSSound::OnRemoveEntity(void) +{ + SndEntLog("stopping\n"); + StopSound(CHAN_BODY, true); +} diff --git a/src/shared/NSSpawnPoint.h b/src/shared/NSSpawnPoint.h index 37964c22..d58e5551 100644 --- a/src/shared/NSSpawnPoint.h +++ b/src/shared/NSSpawnPoint.h @@ -25,9 +25,4 @@ public: /* overrides */ virtual void Respawn(void); - virtual void SpawnKey(string, string); - -private: - vector m_vecMins; - vector m_vecMaxs; }; diff --git a/src/shared/NSSpawnPoint.qc b/src/shared/NSSpawnPoint.qc index f359095f..c5c8e6ea 100644 --- a/src/shared/NSSpawnPoint.qc +++ b/src/shared/NSSpawnPoint.qc @@ -24,33 +24,19 @@ NSSpawnPoint::Respawn(void) { vector newMins, newMaxs; - if (m_vecMins == g_vec_null) { + newMins = GetSpawnVector("mins"); + newMaxs = GetSpawnVector("maxs"); + + if (newMins == g_vec_null) { newMins = VEC_HULL_MIN; newMaxs = VEC_HULL_MAX; - } else { - newMins = m_vecMins; - newMaxs = m_vecMaxs; } - super::Respawn(); - - SetOriginUnstick(GetSpawnVector("origin")); + SetSolid(SOLID_BBOX); SetSize(newMins, newMaxs); + SetOriginUnstick(GetSpawnVector("origin")); SetBotTag(BOTINFO_SPAWNPOINT); + SetSolid(SOLID_NOT); + SetMovetype(MOVETYPE_NONE); + Disappear(); } - -void -NSSpawnPoint::SpawnKey(string keyName, string setValue) -{ - switch (keyName) { - case "mins": - m_vecMins = ReadVector(setValue); - break; - case "maxs": - m_vecMaxs = ReadVector(setValue); - break; - default: - super::SpawnKey(keyName, setValue); - } -} - diff --git a/src/shared/NSSurfacePropEntity.h b/src/shared/NSSurfacePropEntity.h index a1122b28..a40cf1af 100644 --- a/src/shared/NSSurfacePropEntity.h +++ b/src/shared/NSSurfacePropEntity.h @@ -198,6 +198,3 @@ private: #ifdef CLIENT void NSSurfacePropEntity_ReadEntity(bool); #endif - -void entityDamage(entity, entity, entity, string, string, vector, vector, vector); -void radiusDamage(vector, float, int, int, entity, string); diff --git a/src/shared/NSSurfacePropEntity.qc b/src/shared/NSSurfacePropEntity.qc index a87c70b3..93afd375 100644 --- a/src/shared/NSSurfacePropEntity.qc +++ b/src/shared/NSSurfacePropEntity.qc @@ -532,6 +532,9 @@ NSSurfacePropEntity::BreakModel(int damage, vector dir, int location) Disappear(); } + SetSolid(SOLID_NOT); + SetMovetype(MOVETYPE_NONE); + /* handle explosions */ float flExplodeMag, flExplodeRad; flExplodeMag = GetPropData(PROPINFO_EXPLOSIVE_DMG); @@ -543,7 +546,7 @@ NSSurfacePropEntity::BreakModel(int damage, vector dir, int location) } pointparticles(particleeffectnum("fx_explosion.main"), origin, angles, 1); - radiusDamage(origin, flExplodeRad, 0i, (int)flExplodeMag, this, ""); + combat.RadiusDamage(origin, flExplodeRad, 0i, (int)flExplodeMag, this, ""); } } @@ -559,15 +562,6 @@ NSSurfacePropEntity::SetPropData(string type) { m_strPropData = type; _PropDataFinish(); - - /* no surfdata? maybe the propdata has got one set. */ - if (m_iMaterial == -1i) { - string propDataSurf = GetPropData(PROPINFO_SURFACEPROP); - - if (propDataSurf != "") { - SetSurfaceData(propDataSurf); - } - } } void @@ -575,7 +569,7 @@ NSSurfacePropEntity::_SurfaceDataFinish(void) { SurfData_SetStage(m_strSurfData); - if (m_strSurfData) { + if (STRING_SET(m_strSurfData)) { m_iMaterial = SurfData_Finish(); } else { m_iMaterial = -1i; @@ -587,11 +581,20 @@ NSSurfacePropEntity::_PropDataFinish(void) { PropData_SetStage(m_strPropData); - if (m_strPropData) { + if (STRING_SET(m_strPropData)) { m_iPropData = PropData_Finish(); } else { m_iPropData = -1i; } + + /* no surfdata? maybe the propdata has got one set. */ + if (m_iMaterial == -1i && m_iPropData != -1i) { + string propDataSurf = GetPropData(PROPINFO_SURFACEPROP); + + if (STRING_SET(propDataSurf)) { + SetSurfaceData(propDataSurf); + } + } } float @@ -778,7 +781,7 @@ NSSurfacePropEntity::ReceiveEntity(float flNew, float flChanged) void NSSurfacePropEntity::RenderFire(void) { - if (IsOnFire()) { + if (IsOnFire() == true) { vector randomOrg; if (m_flBurnNext < time) { @@ -794,12 +797,15 @@ NSSurfacePropEntity::RenderFire(void) float NSSurfacePropEntity::predraw(void) { - float returnValue = super::predraw(); + float oldEffects = effects; - if (returnValue) { + if (modelindex != 0) { RenderFire(); } + float returnValue = super::predraw(); + + effects = oldEffects; return returnValue; } @@ -824,96 +830,10 @@ NSSurfacePropEntity::SetModel(string newModel) NSRenderableEntity::SetModel(newModel); #ifdef SERVER - if (model && HasPropData() == false) { + if (STRING_SET(model) && HasPropData() == false) { m_iPropData = PropData_ForModel(model); - } -#endif -} - -/* helper functions */ - -void -entityDamage(entity targetEnt, entity inflictingEnt, entity attackingEnt, string damageDef, string weaponDef, vector damageOrigin, vector damageDir, vector hitLocation) -{ -#ifdef SERVER - NSSurfacePropEntity theTarget; - - /* common filters */ - if (targetEnt.takedamage == DAMAGE_NO) { - return; - } - - if (isGodMode(targetEnt) == true) { - return; - } - - theTarget = (NSSurfacePropEntity)targetEnt; - - /* don't use IsAlive(), else we can't gib */ - if (!theTarget.GetHealth()) { - return; - } - - NSDict damageDecl = NSDict::InitWithSpawnData(damageDef); - damageDecl.AddKey("weapon", weaponDef); - theTarget.Damage(inflictingEnt, attackingEnt, damageDecl, 1.0, damageDir, hitLocation); - remove(damageDecl); -#endif -} - -void -radiusDamage(vector damageCenter, float damageRange, int damageMin, int damageMax, entity attackingEnt, string strDamageDecl) -{ -#ifdef SERVER - vector entPos = g_vec_null; - float entDistance = 0.0f; - int newDamage = 0i; - float damageFrac = 0.0f; - vector dmgDir = g_vec_null; - - for (NSSurfacePropEntity e = __NULL__; (e = (NSSurfacePropEntity)nextent(e));) { - if (e.takedamage == DAMAGE_NO) { - continue; - } - - entPos = e.WorldSpaceCenter(); - - /* don't bother if it's not anywhere near us */ - entDistance = length(damageCenter - entPos); - - if (entDistance > damageRange) { - continue; - } - - /* can we physically hit this thing? */ - if (damageMax > 0i) { - if (e.CanBeDamaged(damageCenter, entPos) == false) { - continue; - } - } - - /* calculate new damage values */ - damageFrac = (damageRange - entDistance) / damageRange; - newDamage = (int)lerp(fabs((float)damageMin), (float)damageMax, damageFrac); - dmgDir = dirFromTarget(damageCenter, entPos); - - if (e == attackingEnt) { - newDamage *= 0.5f; - } - - NSDict damageDecl; - - if (STRING_SET(strDamageDecl)) { - int declID = EntityDef_IDFromName(strDamageDecl); - damageDecl = NSDict::InitWithSpawnData(EntityDef_GetSpawnData(declID)); - } else { - damageDecl = spawn(NSDict); - } - - - damageDecl.AddKey("damage", itos(newDamage)); - e.Damage(attackingEnt, attackingEnt, damageDecl, 1.0, dmgDir, trace_endpos); - remove(damageDecl); + m_strPropData = model; + _PropDataFinish(); } #endif } diff --git a/src/shared/NSTalkMonster.h b/src/shared/NSTalkMonster.h index 2f7d4539..3e7b0e3a 100644 --- a/src/shared/NSTalkMonster.h +++ b/src/shared/NSTalkMonster.h @@ -124,9 +124,9 @@ public: /** Called when they want to ask the player a question. */ virtual void TalkPlayerAsk(void); /** Called when they are greeting the player. */ - virtual void TalkPlayerGreet(void); + virtual void SeenPlayer(NSActor); /** Called when they are chit-chatting with the player. */ - virtual void TalkPlayerIdle(void); + virtual void SeenFriend(NSActor); /** Called when they tell the player that they're wounded. */ virtual void TalkPlayerWounded1(void); /** Called when they tell the player that severely wounded. */ diff --git a/src/shared/NSTalkMonster.qc b/src/shared/NSTalkMonster.qc index 6976b0a6..ad8c0550 100644 --- a/src/shared/NSTalkMonster.qc +++ b/src/shared/NSTalkMonster.qc @@ -314,7 +314,7 @@ NSTalkMonster::Speak(string sentence) } void -NSTalkMonster::TalkPlayerGreet(void) +NSTalkMonster::SeenPlayer(NSActor thePlayer) { if (m_iSequenceState != SEQUENCESTATE_NONE) { return; @@ -329,24 +329,14 @@ NSTalkMonster::TalkPlayerGreet(void) return; } - for (entity p = world; (p = find(p, ::classname, "player"));) { - /* Find players in a specific radius */ - if (vlen(p.origin - origin) < PLAYER_DETECT_RADIUS) { - /* If we can't physically see him, don't do anything */ - if (VisibleVec(p.origin + p.view_ofs) == false) - continue; - - Sentence(m_talkPlayerGreet); - m_flNextSentence = time + 10.0; - m_iFlags |= MONSTER_METPLAYER; - m_eLookAt = p; - break; - } - } + Sentence(m_talkPlayerGreet); + m_flNextSentence = time + 10.0; + m_iFlags |= MONSTER_METPLAYER; + m_eLookAt = thePlayer; } void -NSTalkMonster::TalkPlayerIdle(void) +NSTalkMonster::SeenFriend(NSActor theActor) { if (m_iSequenceState != SEQUENCESTATE_NONE) { return; @@ -358,25 +348,8 @@ NSTalkMonster::TalkPlayerIdle(void) return; } - for (entity p = world; (p = find(p, ::classname, "player"));) { - if (IsFriend(p.m_iAlliance) == false) { - continue; - } - - /* Find players in a specific radius */ - if (vlen(p.origin - origin) < PLAYER_DETECT_RADIUS) { - /* If we can't physically see him, don't do anything */ - traceline(origin, p.origin, FALSE, this); - - if (trace_ent != p) { - continue; - } - - Sentence(m_talkPlayerIdle); - m_flNextSentence = time + 10.0; - break; - } - } + Sentence(m_talkPlayerIdle); + m_flNextSentence = time + 10.0; } void @@ -603,7 +576,7 @@ NSTalkMonster::FollowPlayer(void) vector vecParent = m_eFollowingChain.origin; vecParent[2] = origin[2]; - flPlayerDist = vlen(vecParent - origin); + flPlayerDist = distance(vecParent, origin); /* Give up after 1024 units */ if (flPlayerDist > m_flMaxFollowDistance) { @@ -742,11 +715,15 @@ NSTalkMonster::FollowChain(void) void NSTalkMonster::RunAI(void) { + if (GetMovetype() == MOVETYPE_NONE) { + return; + } + SeeThink(); AttackThink(); - TalkPlayerGreet(); FollowChain(); +#if 0 if (m_eFollowing != world && m_iNodes <= 0) { m_eLookAt = m_eFollowing; FollowPlayer(); @@ -756,9 +733,9 @@ NSTalkMonster::RunAI(void) if (random() < 0.5) { TalkPlayerAsk(); } else { - TalkPlayerIdle(); } } +#endif } void diff --git a/src/shared/NSWeapon.h b/src/shared/NSWeapon.h index a9bbfe98..3b3cd0e3 100644 --- a/src/shared/NSWeapon.h +++ b/src/shared/NSWeapon.h @@ -41,13 +41,15 @@ typedef enumflags typedef enum { WEAPONSTATE_IDLE, - WEAPONSTATE_RELOAD_START, - WEAPONSTATE_RELOAD, - WEAPONSTATE_RELOAD_END, + WEAPONSTATE_COCK, WEAPONSTATE_CHARGING, WEAPONSTATE_FIRELOOP, WEAPONSTATE_RELEASED, - WEAPONSTATE_OVERHEATED + WEAPONSTATE_OVERHEATED, + WEAPONSTATE_DRAW, + WEAPONSTATE_RELOAD_START, + WEAPONSTATE_RELOAD, + WEAPONSTATE_RELOAD_END } nsweapon_state_t; string nsweapon_state_s[] = @@ -169,6 +171,7 @@ NSWeapon:NSItem public: void NSWeapon(void); + virtual void InputFrame(void); virtual void AddedToInventory(void); virtual void RemovedFromInventory(void); @@ -193,6 +196,7 @@ public: virtual void ReceiveEvent(float); #endif + virtual bool UsesSecondaryAmmo(void); virtual bool IsEmpty(void); virtual bool IsWeapon(void); virtual bool HasReserveAmmo(void); @@ -218,7 +222,7 @@ public: nonvirtual void SetWorldModel(string); nonvirtual void SetPlayerModel(string); nonvirtual void SetWeaponFrame(float); - nonvirtual void PlaySound(string, bool); + nonvirtual void PlaySound(string, float, bool); /* state */ nonvirtual nsweapon_state_t GetWeaponState(void); @@ -284,6 +288,12 @@ private: #endif /* weapon related spawn keys */ + string m_strWeaponTitle; + int m_iHudSlot; + int m_iHudSlotPos; + string m_icon; + string m_iconSel; + string m_strWeaponViewModel; string m_strWeaponPlayerModel; string m_strWeaponScript; @@ -350,6 +360,10 @@ private: string m_fiSndFireStart; string m_fiSndFireStop; string m_fiSndFireLoop; + bool m_fiDrawAfterRelease; + + bool m_fiCocks; + string m_fiSndCock; /* overheating */ float m_fiOverheatLength; @@ -370,55 +384,3 @@ private: .NSWeapon m_nextWeapon; .NSWeapon m_prevWeapon; -/* Helper functions for plugins, the rest of the codebase etc. - -These are, according to IW, common operations. Makes sense to -handle the implementation ourselves as it'll prevent -entityDefs changing from breaking plugins as a result. -Some of these don't just do direct look-ups of keys. */ - -/** @return the "attack" type of the weapon. -@param weaponDef the name of the entityDef that defines the weapon. -@return Attack type of the weapon. */ -string weaponType(string weaponDef); - -/** @return The amount of ammo the specified weapon is meant to start with, when first given to the player. This can be distributed to both clip and reserve ammo types. -@param weaponDef the name of the entityDef that defines the weapon. */ -int weaponStartAmmo(string weaponDef); - -/** @return The amount of ammo the weapon can hold in total when it comes to reserve ammo. So this is really returning the max ammo of a given ammo type. -@param weaponDef the name of the entityDef that defines the weapon. */ -int weaponMaxAmmo(string weaponDef); - -/** @return Whether the weapon is semi automatic. -@param weaponDef the name of the entityDef that defines the weapon. */ -bool weaponIsSemiAuto(string weaponDef); - -/** @return How this weapon is stored. Usually "item", unless it's temporary. -@param weaponDef the name of the entityDef that defines the weapon. */ -string weaponInventoryType(string weaponDef); - -/** @return The delay (in seconds) betwen shots of the specified weapon. -@param weaponDef the name of the entityDef that defines the weapon. */ -float weaponFireTime(string weaponDef); - -/** -@return The delay (in seconds) betwen shots of the specified weapon. -@param weaponDef the name of the entityDef that defines the weapon. */ -int weaponClipSize(string weaponDef); - -/** -@return The 'class' of weapon. Not spawnclass. -@param weaponDef the name of the entityDef that defines the weapon.*/ -string weaponClass(string weaponDef); - -/** -@return true/false whether the weapon takes its ammo only through its clip. -@param weaponDef the name of the entityDef that defines the weapon.*/ -bool isWeaponClipOnly(string weaponDef); - -/** -@return true/false whether or not the weapon creates a timed, fused detonating charge of sorts. -@param weaponDef the name of the entityDef that defines the weapon.*/ -bool isWeaponDetonationTimed(string weaponDef); - diff --git a/src/shared/NSWeapon.qc b/src/shared/NSWeapon.qc index 748f27ff..0dfa0554 100644 --- a/src/shared/NSWeapon.qc +++ b/src/shared/NSWeapon.qc @@ -154,6 +154,8 @@ NSWeapon::UpdateFireInfoCache(void) /* only check if it's present. */ m_bHasLoop = GetSubDefBool(m_strLastFireInfo, "loop"); + m_fiCocks = GetSubDefBool(m_strLastFireInfo, "cocks"); + m_fiDrawAfterRelease = GetSubDefBool(m_strLastFireInfo, "drawAfterRelease"); /* keep the last valid value (don't 0.0f it) to prevent overlay dropouts. */ if (m_fiOverheatPoints) { @@ -238,6 +240,7 @@ NSWeapon::Spawned(void) SetViewModel(m_strWeaponViewModel); SetWorldModel(model); SetPlayerModel(m_strWeaponPlayerModel); + _isWeapon = true; } void @@ -373,10 +376,6 @@ NSWeapon::Restore(string strKey, string strValue) float NSWeapon::SendEntity(entity ePEnt, float flChanged) { - if (InInventory() == false) { - return NSItem::SendEntity(ePEnt, flChanged); - } - /* item is in somebody elses inventory. */ if (InInventory() == true && ePEnt != GetOwner()) { return (false); @@ -398,7 +397,7 @@ NSWeapon::SendEntity(entity ePEnt, float flChanged) SENDENTITY_ANGLE(angles[0], WEAPONFL_CHANGED_ANGLES) SENDENTITY_ANGLE(angles[1], WEAPONFL_CHANGED_ANGLES) SENDENTITY_ANGLE(angles[2], WEAPONFL_CHANGED_ANGLES) - SENDENTITY_FLOAT(entityDefID, WEAPONFL_CHANGED_MODELINDEX) + SENDENTITY_INT(entityDefID, WEAPONFL_CHANGED_MODELINDEX) SENDENTITY_SHORT(m_viewModel, WEAPONFL_CHANGED_MODELINDEX) SENDENTITY_FLOAT(m_flFireRate, WEAPONFL_CHANGED_MODELINDEX) SENDENTITY_BYTE(solid, WEAPONFL_CHANGED_SOLID) @@ -521,7 +520,7 @@ NSWeapon::ReceiveEntity(float flNew, float flChanged) READENTITY_ANGLE(angles[0], WEAPONFL_CHANGED_ANGLES) READENTITY_ANGLE(angles[1], WEAPONFL_CHANGED_ANGLES) READENTITY_ANGLE(angles[2], WEAPONFL_CHANGED_ANGLES) - READENTITY_FLOAT(entityDefID, WEAPONFL_CHANGED_MODELINDEX) + READENTITY_INT(entityDefID, WEAPONFL_CHANGED_MODELINDEX) READENTITY_SHORT(m_viewModel, WEAPONFL_CHANGED_MODELINDEX) READENTITY_FLOAT(m_flFireRate, WEAPONFL_CHANGED_MODELINDEX) READENTITY_BYTE(solid, WEAPONFL_CHANGED_SOLID) @@ -686,6 +685,10 @@ NSWeapon::_CacheWeaponDefVariables(void) string muzzleModel; string ammoRequired; + m_strWeaponTitle = GetDefString("inv_name"); + m_iHudSlot = GetDefInt("hudSlot"); + m_iHudSlotPos = GetDefInt("hudSlotPos"); + /* movement vars */ m_flSpeedMod = GetDefFloat("speed_mod"); m_bBuggyIdleAnim = GetDefBool("buggyIdleAnim"); @@ -753,6 +756,7 @@ NSWeapon::_SwitchedToCallback(void) #ifdef CLIENT pSeat->m_iHUDWeaponSelected = GetSharedID(); PredictPreFrame(); + HUD_SwitchedToWeapon(classname); #endif } @@ -855,7 +859,7 @@ NSWeapon::Draw(void) } #ifdef SERVER - PlaySound(GetDefString("snd_draw"), false); + PlaySound(GetDefString("snd_draw"), CHAN_AUTO, false); #endif SetAttackNext(drawTime); @@ -975,6 +979,12 @@ NSWeapon::FiredWeaponAttack(string fireInfo) } } +void +NSWeapon::InputFrame(void) +{ + +} + void NSWeapon::ReleasedWeaponAttack(string fireInfo) { @@ -1030,12 +1040,12 @@ NSWeapon::Attack(string fireInfo) } /* will release projectile upon release. */ - if (m_fiOnRelease != "") { - m_fiWillRelease = true; + if (!(ourOwner.vv_flags & VFL_PRIMEDFUSE) && STRING_SET(m_fiOnRelease)) { + _SetWeaponState(WEAPONSTATE_RELEASED); ourOwner.vv_flags |= VFL_PRIMEDFUSE; } - if (UseAmmo(fireInfo) == false) { + if (IsEmpty() == true) { return; } @@ -1048,6 +1058,7 @@ NSWeapon::Attack(string fireInfo) #ifdef SERVER ourOwner.nadeCookingTime = time; + PlaySound(GetSubDefString(fireInfo, "snd_delay"), CHAN_WEAPON, false); #endif /* mark as charging, play loop anim in Idle() next */ @@ -1055,8 +1066,14 @@ NSWeapon::Attack(string fireInfo) SetWeaponFrame(shotAnim); _SetWeaponState(WEAPONSTATE_CHARGING); return; + } if (UseAmmo(fireInfo) == false) { + return; } } else { + if (UseAmmo(fireInfo) == false) { + return; + } + #ifdef SERVER ourOwner.nadeCookingTime = time; #endif @@ -1112,6 +1129,8 @@ NSWeapon::Attack(string fireInfo) if (m_flOverheating >= m_fiOverheatLength) { _SetWeaponState(WEAPONSTATE_OVERHEATED); } + } else if (m_fiCocks) { + _SetWeaponState(WEAPONSTATE_COCK); } float animTime = frameduration(m_viewModel, shotAnim); @@ -1165,17 +1184,17 @@ NSWeapon::_SwitchedWeaponMode(void) } void -NSWeapon::PlaySound(string soundDef, bool clientOnly) +NSWeapon::PlaySound(string soundDef, float soundChannel, bool clientOnly) { #ifdef CLIENT if (clientOnly) { - Sound_Play(owner, CHAN_WEAPON, soundDef); + Sound_Play(owner, soundChannel, soundDef); } #endif #ifdef SERVER if (!clientOnly) { - Sound_Play(owner, CHAN_WEAPON, soundDef); + Sound_Play(owner, soundChannel, soundDef); } #endif } @@ -1240,7 +1259,7 @@ NSWeapon::Idle(void) idleAnim = GetSubDefAct(m_strLastFireInfo, "reloadStart"); _SetWeaponState(WEAPONSTATE_RELOAD); #ifdef SERVER - PlaySound(GetDefString("snd_reload_start"), false); + PlaySound(GetDefString("snd_reload_start"), CHAN_AUTO, false); #endif SetAttackNext(frameduration(m_viewModel, idleAnim)); break; @@ -1260,7 +1279,7 @@ NSWeapon::Idle(void) reloadTime = m_flReloadSpeed; } #ifdef SERVER - PlaySound(GetDefString("snd_reload"), false); + PlaySound(GetDefString("snd_reload"), CHAN_AUTO, false); #endif SetWeaponFrame(idleAnim); SetIdleNext(reloadTime); @@ -1271,7 +1290,7 @@ NSWeapon::Idle(void) idleAnim = GetSubDefAct(m_strLastFireInfo, "reloadEnd"); _SetWeaponState(WEAPONSTATE_IDLE); #ifdef SERVER - PlaySound(GetDefString("snd_reload_end"), false); + PlaySound(GetDefString("snd_reload_end"), CHAN_AUTO, false); #endif SetAttackNext(frameduration(m_viewModel, idleAnim)); break; @@ -1281,11 +1300,38 @@ NSWeapon::Idle(void) case WEAPONSTATE_CHARGING: idleAnim = GetSubDefAct(m_strLastFireInfo, "loop"); break; + case WEAPONSTATE_COCK: + //breakpoint(); + idleAnim = GetSubDefAct(m_strLastFireInfo, "cock"); +#ifdef SERVER + PlaySound(GetDefString("snd_cock"), CHAN_AUTO, false); +#endif + _SetWeaponState(WEAPONSTATE_IDLE); + SetAttackNext(frameduration(m_viewModel, idleAnim)); + break; case WEAPONSTATE_RELEASED: //breakpoint(); + + if (m_fiSndRelease) { + ourOwner.StartSoundDef(m_fiSndRelease, CHAN_WEAPON, true); + } + + UseAmmo(m_strLastFireInfo); + ReleasedWeaponAttack(m_strLastFireInfo); + ourOwner.vv_flags &= ~VFL_PRIMEDFUSE; idleAnim = GetSubDefAct(m_strLastFireInfo, "release"); - _SetWeaponState(WEAPONSTATE_IDLE); + SetAttackNext(frameduration(m_viewModel, idleAnim)); + + if (m_fiDrawAfterRelease == true) { + _SetWeaponState(WEAPONSTATE_DRAW); + } else { + _SetWeaponState(WEAPONSTATE_IDLE); + } break; + case WEAPONSTATE_DRAW: + Draw(); + _SetWeaponState(WEAPONSTATE_IDLE); + return; case WEAPONSTATE_OVERHEATED: /* prevent fire for the next N seconds */ _SetWeaponState(WEAPONSTATE_IDLE); @@ -1376,9 +1422,9 @@ NSWeapon::SecondaryAttack(void) #ifdef SERVER if (ourOwner.viewzoom == 1.0) { - PlaySound(GetDefString("snd_lower_scope"), false); + PlaySound(GetDefString("snd_lower_scope"), CHAN_AUTO, false); } else { - PlaySound(GetDefString("snd_raise_scope"), false); + PlaySound(GetDefString("snd_raise_scope"), CHAN_AUTO, false); } #endif @@ -1631,31 +1677,29 @@ NSWeapon::Release(void) NSClientPlayer ourOwner = (NSClientPlayer)GetOwner(); ourOwner.gflags &= ~GF_SEMI_TOGGLED; - if (m_fiWillRelease) { - /* delayed shot release */ - idleAnim = GetSubDefAct(m_strLastFireInfo, "release"); - - if (m_fiSndRelease) { - ourOwner.StartSoundDef(m_fiSndRelease, CHAN_WEAPON, true); - } - - ReleasedWeaponAttack(m_strLastFireInfo); - m_fiWillRelease = false; - - if (idleAnim >= 0) { - SetWeaponFrame(idleAnim); - } - - SetAttackNext(1.0f); - SetIdleNext(1.0f); - ourOwner.vv_flags &= ~VFL_PRIMEDFUSE; - return; + /* we're allowed to release any time. allow it! */ + if (ourOwner.vv_flags & VFL_PRIMEDFUSE) { + _SetWeaponState(WEAPONSTATE_RELEASED); + SetIdleNext(0.0f); } + if (GetWeaponState() == WEAPONSTATE_CHARGING) { + if (CanFire() == true) { + /* hack to get around the ammo usage when charging */ + float oldChargeTime = m_fiChargeTime; + m_fiChargeTime = 0.0f; + Attack(m_strLastFireInfo); + m_fiChargeTime = oldChargeTime; + return; + } + } + +#if 0 /* already in a reload? */ if (!(m_dState >= WEAPONSTATE_RELOAD_START && m_dState <= WEAPONSTATE_RELOAD_END)) { _SetWeaponState(WEAPONSTATE_IDLE); } +#endif #ifdef SERVER if (m_bFiring == true) { @@ -1840,93 +1884,9 @@ NSWeapon::GetPreviousWeapon(void) return (m_prevWeapon); } -/* required because we might need to look it up inside the -info for the primary attack mode. */ -static string -NSWeapon_GetPrimaryKeyValue(string weaponDef, string keyName) -{ - string fireInfo1 = EntityDef_GetKeyValue(weaponDef, "def_fireInfo"); - string defValue = EntityDef_GetKeyValue(weaponDef, keyName); - string fireInfoValue = EntityDef_GetKeyValue(fireInfo1, keyName); - - /* fireinfo takes priority */ - if (fireInfoValue) { - return (fireInfoValue); - } - - return (defValue); -} - -string -weaponType(string weaponDef) -{ - return ("unknown"); -} - -int -weaponStartAmmo(string weaponDef) -{ - return (int)stof(EntityDef_GetKeyValue(weaponDef, "clipSize")); -} - -int -weaponMaxAmmo(string weaponDef) -{ - string ammoType = NSWeapon_GetPrimaryKeyValue(weaponDef, "ammoType"); - return (ammoMaxForName(ammoType)); -} - bool -weaponIsSemiAuto(string weaponDef) +NSWeapon::UsesSecondaryAmmo(void) { - return (bool)stof(NSWeapon_GetPrimaryKeyValue(weaponDef, "semiAuto")); -} - -string -weaponInventoryType(string weaponDef) -{ - return ("item"); -} - -float -weaponFireTime(string weaponDef) -{ - return stof(NSWeapon_GetPrimaryKeyValue(weaponDef, "fireRate")); -} - -int -weaponClipSize(string weaponDef) -{ - return (int)stoi(EntityDef_GetKeyValue(weaponDef, "clipSize")); -} - -string -weaponClass(string weaponDef) -{ - return ("unknown"); -} - -bool -isWeaponClipOnly(string weaponDef) -{ - int clipSize = (int)stoi(EntityDef_GetKeyValue(weaponDef, "clipSize")); - string ammoType = NSWeapon_GetPrimaryKeyValue(weaponDef, "ammoType"); - - /* no ammo type... */ - if (!ammoType) { - /* but a clip is defined */ - if (clipSize > 0i) { - return (true); - } - } - return (false); -} - -bool -isWeaponDetonationTimed(string weaponDef) -{ - string projectileDef = NSWeapon_GetPrimaryKeyValue(weaponDef, "def_projectile"); - bool isFused = (bool)stof(EntityDef_GetKeyValue(projectileDef, "detonate_on_fuse")); - return (isFused); + return (m_secondaryAmmoType && m_primaryAmmoType != m_secondaryAmmoType) ? (true) : (false); } diff --git a/src/shared/ammo.qc b/src/shared/ammo.qc index bb53c02f..2fc81eba 100644 --- a/src/shared/ammo.qc +++ b/src/shared/ammo.qc @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2016-2024 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ /** Data holding ammo variant entries. */ typedef struct @@ -52,7 +67,7 @@ Ammo_Init(void) string ammoTypeData; if (ammoTypeID == -1) { - NSError("Decl `ammo_types` not defined in `def/`. Ammo unavailable."); + NSWarning("Decl `ammo_types` not defined in `def/`. Ammo unavailable."); return; } diff --git a/src/shared/api.h b/src/shared/api.h new file mode 100644 index 00000000..4e1a9e49 --- /dev/null +++ b/src/shared/api.h @@ -0,0 +1,505 @@ +/* + * Copyright (c) 2016-2024 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + + +/** @defgroup sharedAPI Shared multiprogs API + @brief Shared multiprogs API + @ingroup multiprogs + @ingroup shared + +APIs used by both client and server progs. + +@{ +*/ + +typedef struct +{ + /** Returns the name of the specified ammo type. Returns __NULL__ when invalid. */ + string NameForNum(int); + /** Returns the ammo id of a given name of ammo. Return -1 when invalid. */ + int NumForName(string); + /** Returns the max ammo given name of ammo. Returns 0 when invalid. */ + int MaxForName(string); + /** Returns the max ammo given name of ammo. Returns 0 when invalid. */ + int MaxForNum(int); +} ammoAPI_t; + +ammoAPI_t ammo; + + +/* CVar library */ +typedef struct +{ + /** Returns the string value of a console variable. + + @param cvarName specifies the console variable key to query. + @return The value in string format. */ + string GetString(string cvarName); + /** Returns the integer value of a console variable. + + @param cvarName specifies the console variable key to query. + @return The value in integer format. */ + int GetInteger(string cvarName); + /** Returns the floating-point value of a console variable. + + @param cvarName specifies the console variable key to query. + @return The value in floating-point format. */ + float GetFloat(string cvarName); + /** Returns the boolean value of a console variable. + + @param cvarName specifies the console variable key to query. + @return The value in boolean form. */ + bool GetBool(string cvarName); + /** Returns the vector value of a console variable. + + @param cvarName specifies the console variable key to query. + @return The value in vector form. */ + vector GetVector(string cvarName); + /** Sets the specified console variable to a set string value. + + @param cvarName specifies the console variable to set. + @param setValue specifies the value of said key. */ + void SetString(string cvarName, string setValue); + /** Sets the specified console variable to a set integer value. + + @param cvarName specifies the console variable to set. + @param setValue specifies the value of said key. */ + void SetInteger(string cvarName, int setValue); + /** Sets the specified console variable to a set boolean value. + + @param cvarName specifies the console variable to set. + @param setValue specifies the value of said key. */ + void SetBool(string cvarName, bool setValue); + /** Sets the specified console variable to a set floating-point value. + + @param cvarName specifies the console variable to set. + @param setValue specifies the value of said key. */ + void SetFloat(string cvarName, float setValue); + /** Sets the specified console variable to a set vector. + + @param cvarName specifies the console variable to set. + @param setValue specifies the value of said key. */ + void SetVector(string cvarName, vector setValue); +} cvarAPI_t; + +cvarAPI_t cvars; + +/* ServerInfo library */ +typedef struct +{ + /** Returns the string value of a server info-key. + + @param serverKey specifies the server info-key to query. + @return The value in string format. */ + string GetString(string serverKey); + /** Returns the integer value of a server info-key. + + @param serverKey specifies the server info-key to query. + @return The value in integer format. */ + int GetInteger(string serverKey); + /** Returns the floating-point value of a server info-key. + + @param serverKey specifies the server info-key to query. + @return The value in floating-point format. */ + float GetFloat(string serverKey); + /** Returns the boolean value of a server info-key. + + @param serverKey specifies the server info-key to query. + @return The value in boolean form. */ + bool GetBool(string serverKey); + /** Returns the vector value of a server info-key. + + @param serverKey specifies the server info-key to query. + @return The value in vector form. */ + vector GetVector(string serverKey); + /** Sets the specified server info-key to a set string value. + + @param serverKey specifies the server info-key to set. + @param setValue specifies the value of said key. */ + void SetString(string serverKey, string setValue); + /** Sets the specified server info-key to a set integer value. + + @param serverKey specifies the server info-key to set. + @param setValue specifies the value of said key. */ + void SetInteger(string serverKey, int setValue); + /** Sets the specified server info-key to a set boolean value. + + @param serverKey specifies the server info-key to set. + @param setValue specifies the value of said key. */ + void SetBool(string serverKey, bool setValue); + /** Sets the specified server info-key to a set floating-point value. + + @param serverKey specifies the server info-key to set. + @param setValue specifies the value of said key. */ + void SetFloat(string serverKey, float setValue); + /** Sets the specified server info-key to a set vector. + + @param serverKey specifies the server info-key to set. + @param setValue specifies the value of said key. */ + void SetVector(string serverKey, vector setValue); +} serverinfoAPI_t; + +serverinfoAPI_t serverinfo; + +/* UserInfo library */ +typedef struct +{ + /** Returns the string value of a user info-key. + + @param clientEnt specifies which user to query. + @param userKey specifies the user info-key to query. + @return The value in string format. */ + string GetString(entity clientEnt, string userKey); + /** Returns the integer value of a user info-key. + + @param clientEnt specifies which user to query. + @param userKey specifies the user info-key to query. + @return The value in integer format. */ + int GetInteger(entity clientEnt, string userKey); + /** Returns the floating-point value of a user info-key. + + @param clientEnt specifies which user to query. + @param userKey specifies the user info-key to query. + @return The value in floating-point format. */ + float GetFloat(entity clientEnt, string userKey); + /** Returns the boolean value of a user info-key. + + @param clientEnt specifies which user to query. + @param userKey specifies the user info-key to query. + @return The value in boolean form. */ + bool GetBool(entity clientEnt, string userKey); + /** Returns the vector value of a user info-key. + + @param clientEnt specifies which user to query. + @param userKey specifies the user info-key to query. + @return The value in vector form. */ + vector GetVector(entity clientEnt, string userKey); + /** Sets the specified user info-key to a set string value. + + @param clientEnt specifies which user to query. + @param userKey specifies the user info-key to set. + @param setValue specifies the value of said key. */ + void SetString(entity clientEnt, string userKey, string setValue); + /** Sets the specified user info-key to a set integer value. + + @param clientEnt specifies which user to query. + @param userKey specifies the user info-key to set. + @param setValue specifies the value of said key. */ + void SetInteger(entity clientEnt, string userKey, int setValue); + /** Sets the specified user info-key to a set boolean value. + + @param clientEnt specifies which user to query. + @param userKey specifies the user info-key to set. + @param setValue specifies the value of said key. */ + void SetBool(entity clientEnt, string userKey, bool setValue); + /** Sets the specified user info-key to a set floating-point value. + + @param clientEnt specifies which user to query. + @param userKey specifies the user info-key to set. + @param setValue specifies the value of said key. */ + void SetFloat(entity clientEnt, string userKey, float setValue); + /** Sets the specified user info-key to a set vector. + + @param clientEnt specifies which user to query. + @param userKey specifies the user info-key to set. + @param setValue specifies the value of said key. */ + void SetVector(entity clientEnt, string userKey, vector setValue); +} userinfoAPI_t; + +userinfoAPI_t userinfo; + +typedef struct +{ + /** @return the "attack" type of the weapon. + @param weaponDef the name of the entityDef that defines the weapon. + @return Attack type of the weapon. */ + string Type(string weaponDef); + /** @return The amount of ammo the specified weapon is meant to start with, when first given to the player. This can be distributed to both clip and reserve ammo types. + @param weaponDef the name of the entityDef that defines the weapon. */ + int StartAmmo(string weaponDef); + /** @return The amount of ammo the weapon can hold in total when it comes to reserve ammo. So this is really returning the max ammo of a given ammo type. + @param weaponDef the name of the entityDef that defines the weapon. */ + int MaxAmmo(string weaponDef); + /** @return Whether the weapon is semi automatic. + @param weaponDef the name of the entityDef that defines the weapon. */ + bool IsSemiAuto(string weaponDef); + + /** @return How this weapon is stored. Usually "item", unless it's temporary. + @param weaponDef the name of the entityDef that defines the weapon. */ + string InventoryType(string weaponDef); + /** @return The delay (in seconds) betwen shots of the specified weapon. + @param weaponDef the name of the entityDef that defines the weapon. */ + float FireTime(string weaponDef); + /** + @return The delay (in seconds) betwen shots of the specified weapon. + @param weaponDef the name of the entityDef that defines the weapon. */ + int ClipSize(string weaponDef); + /** + @return The 'class' of weapon. Not spawnclass. + @param weaponDef the name of the entityDef that defines the weapon.*/ + string Class(string weaponDef); + /** + @return true/false whether the weapon takes its ammo only through its clip. + @param weaponDef the name of the entityDef that defines the weapon.*/ + bool IsClipOnly(string weaponDef); + /** + @return true/false whether or not the weapon creates a timed, fused detonating charge of sorts. + @param weaponDef the name of the entityDef that defines the weapon.*/ + bool IsDetonationTimed(string weaponDef); +} weaponInfo_t; + +weaponInfo_t weaponInfo; + +/* Team library */ +typedef struct +{ + int BestAutoJoinTeam(void); + int TeamCount(void); + vector Color(int); + string Name(int); + int Score(int); + string SpawnPoint(int); + int NumPlayers(int); + int NumAlivePlayers(int); + int NumDeadPlayers(int); + int TotalDeaths(int); + int TotalFrags(int); + bool Valid(int); + + void AddScore(int, int); + void SetScore(int, int); + entity RandomPlayer(int); + + + /** Sets up a team for the current session. Will flush the team specific scores. + + @param teamID specifies which team slot to occupy. + @param teamTitle specifies the title of the team. + @param teamColor specifies the color of the team (e.g. [0, 255, 0] for green). + @param openTeam specifies whether people can join the team manually. */ + void SetUp(int teamID, string teamTitle, vector teamColor, bool openTeam); + + + void SetSpawnPoint(int, string); +} teamAPI_t; + +teamAPI_t teams; + + + +/* ServerInfo library */ +typedef struct +{ + /** Returns the string value of a EntityDef key. + + @param defName specifies the EntityDef name in question + @param keyName specifies the EntityDef key to query. + @return The value in string format. */ + string GetString(string defName, string keyName); + /** Returns the integer value of a EntityDef key. + + @param defName specifies the EntityDef name in question + @param keyName specifies the EntityDef key to query. + @return The value in integer format. */ + int GetInteger(string defName, string keyName); + /** Returns the floating-point value of a EntityDef key. + + @param defName specifies the EntityDef name in question + @param keyName specifies the EntityDef key to query. + @return The value in floating-point format. */ + float GetFloat(string defName, string keyName); + /** Returns the boolean value of a EntityDef key. + + @param defName specifies the EntityDef name in question + @param keyName specifies the EntityDef key to query. + @return The value in boolean form. */ + bool GetBool(string defName, string keyName); + /** Returns the vector value of a EntityDef key. + + @param defName specifies the EntityDef name in question + @param keyName specifies the EntityDef key to query. + @return The value in vector form. */ + vector GetVector(string defName, string keyName); +} entityDefAPI_t; + +entityDefAPI_t entityDef; + +typedef string decl; + +typedef struct +{ + /** Returns the name of a new decl in which you can store + * key/value pairs in. */ + decl New(void); + + /** Returns the string value of a key from a decl. + + @param declHandle is the `decl` reference to update. + @param keyName specifies the name of the key to query within the decl. + @return The key its value in string format. */ + string GetString(decl declHandle, string keyName); + /** Returns the integer value of a decl key. + + @param declHandle is the `decl` reference to update. + @param keyName specifies the name of the key to query within the decl. + @return The key its value in integer format. */ + int GetInteger(decl declHandle, string keyName); + /** Returns the floating-point value of a decl key. + + @param declHandle is the `decl` reference to update. + @param keyName specifies the name of the key to query within the decl. + @return The key its value in floating-point format. */ + float GetFloat(decl declHandle, string keyName); + /** Returns the boolean value of a decl key. + + @param declHandle is the `decl` reference to update. + @param keyName specifies the name of the key to query within the decl. + @return The key its value in boolean form. */ + bool GetBool(decl declHandle, string keyName); + /** Returns the vector value of a decl key. + + @param declHandle is the `decl` reference to update. + @param keyName specifies the name of the key to query within the decl. + @return The key its value in vector form. */ + vector GetVector(decl declHandle, string keyName); + + /** Adds/updates a named key within a decl with + a new string value. + + @param declHandle is the `decl` reference to update. + @param keyName specifies the key to set. + @param setValue specifies the value we'll set the key to. */ + void AddKey(decl declHandle, string keyName, string setValue); + + /** Removes a named key from a decl entirely. + + @param declHandle is the `decl` reference to update. + @param keyName specifies the key to remove. */ + void RemoveKey(decl declHandle, string keyName); + + /** Removes a named decl from the game. + + @param declHandle specifies the decl to delete. */ + void Delete(decl declHandle); +} declAPI_t; + +declAPI_t declManager; + +__variant +linkToSharedProgs(string funcName) +{ + static void empty(void) + { + print("Called unimplemented shared API call.\n"); + breakpoint(); + } + + float func = externvalue( 0, funcName); + + if (func) { + return ((__variant)func); + } else { + return (empty); + } +} + +void +_shared_main(void) +{ + ammo.NameForNum = linkToSharedProgs("SHPF_ammo_NameForNum"); + ammo.NumForName = linkToSharedProgs("SHPF_ammo_NumForName"); + ammo.MaxForName = linkToSharedProgs("SHPF_ammo_MaxForName"); + ammo.MaxForNum = linkToSharedProgs("SHPF_ammo_MaxForNum"); + + cvars.SetString = linkToSharedProgs("SHPF_cvars_SetString"); + cvars.SetBool = linkToSharedProgs("SHPF_cvars_SetBool"); + cvars.SetInteger = linkToSharedProgs("SHPF_cvars_SetInteger"); + cvars.SetFloat = linkToSharedProgs("SHPF_cvars_SetFloat"); + cvars.SetVector = linkToSharedProgs("SHPF_cvars_SetVector"); + cvars.GetString = linkToSharedProgs("SHPF_cvars_GetString"); + cvars.GetInteger = linkToSharedProgs("SHPF_cvars_GetInteger"); + cvars.GetBool = linkToSharedProgs("SHPF_cvars_GetBool"); + cvars.GetFloat = linkToSharedProgs("SHPF_cvars_GetFloat"); + cvars.GetVector = linkToSharedProgs("SHPF_cvars_GetVector"); + + declManager.New = linkToSharedProgs("SHPF_declManager_New"); + declManager.GetFloat = linkToSharedProgs("SHPF_declManager_GetFloat"); + declManager.GetString = linkToSharedProgs("SHPF_declManager_GetString"); + declManager.GetVector = linkToSharedProgs("SHPF_declManager_GetVector"); + declManager.GetBool = linkToSharedProgs("SHPF_declManager_GetBool"); + declManager.AddKey = linkToSharedProgs("SHPF_declManager_AddKey"); + declManager.RemoveKey = linkToSharedProgs("SHPF_declManager_RemoveKey"); + declManager.Delete = linkToSharedProgs("SHPF_declManager_Delete"); + + userinfo.SetString = linkToSharedProgs("SHPF_userinfo_SetString"); + userinfo.SetBool = linkToSharedProgs("SHPF_userinfo_SetBool"); + userinfo.SetInteger = linkToSharedProgs("SHPF_userinfo_SetInteger"); + userinfo.SetFloat = linkToSharedProgs("SHPF_userinfo_SetFloat"); + userinfo.SetVector = linkToSharedProgs("SHPF_userinfo_SetVector"); + userinfo.GetString = linkToSharedProgs("SHPF_userinfo_GetString"); + userinfo.GetInteger = linkToSharedProgs("SHPF_userinfo_GetInteger"); + userinfo.GetBool = linkToSharedProgs("SHPF_userinfo_GetBool"); + userinfo.GetFloat = linkToSharedProgs("SHPF_userinfo_GetFloat"); + userinfo.GetVector = linkToSharedProgs("SHPF_userinfo_GetVector"); + + serverinfo.SetString = linkToSharedProgs("SHPF_serverinfo_SetString"); + serverinfo.SetBool = linkToSharedProgs("SHPF_serverinfo_SetBool"); + serverinfo.SetInteger = linkToSharedProgs("SHPF_serverinfo_SetInteger"); + serverinfo.SetFloat = linkToSharedProgs("SHPF_serverinfo_SetFloat"); + serverinfo.SetVector = linkToSharedProgs("SHPF_serverinfo_SetVector"); + serverinfo.GetString = linkToSharedProgs("SHPF_serverinfo_GetString"); + serverinfo.GetInteger = linkToSharedProgs("SHPF_serverinfo_GetInteger"); + serverinfo.GetBool = linkToSharedProgs("SHPF_serverinfo_GetBool"); + serverinfo.GetFloat = linkToSharedProgs("SHPF_serverinfo_GetFloat"); + serverinfo.GetVector = linkToSharedProgs("SHPF_serverinfo_GetVector"); + + teams.BestAutoJoinTeam = linkToSharedProgs("SHPF_teams_BestAutoJoinTeam"); + teams.TeamCount = linkToSharedProgs("SHPF_teams_TeamCount"); + teams.Color = linkToSharedProgs("SHPF_teams_Color"); + teams.Name = linkToSharedProgs("SHPF_teams_Name"); + teams.Score = linkToSharedProgs("SHPF_teams_Score"); + teams.SpawnPoint = linkToSharedProgs("SHPF_teams_SpawnPoint"); + teams.NumPlayers = linkToSharedProgs("SHPF_teams_NumPlayers"); + teams.NumAlivePlayers = linkToSharedProgs("SHPF_teams_NumAlivePlayers"); + teams.NumDeadPlayers = linkToSharedProgs("SHPF_teams_NumDeadPlayers"); + teams.TotalDeaths = linkToSharedProgs("SHPF_teams_TotalDeaths"); + teams.TotalFrags = linkToSharedProgs("SHPF_teams_TotalFrags"); + teams.Valid = linkToSharedProgs("SHPF_teams_Valid"); + teams.RandomPlayer = linkToSharedProgs("SHPF_teams_RandomPlayer"); + + /* server */ + teams.AddScore = linkToSharedProgs("SHPF_teams_AddScore"); + teams.SetScore = linkToSharedProgs("SHPF_teams_SetScore"); + teams.SetUp = linkToSharedProgs("SHPF_teams_SetUp"); + teams.SetSpawnPoint = linkToSharedProgs("SHPF_teams_SetSpawnPoint"); + + weaponInfo.Type = linkToSharedProgs("SHPF_weaponInfo_Type"); + weaponInfo.StartAmmo = linkToSharedProgs("SHPF_weaponInfo_StartAmmo"); + weaponInfo.MaxAmmo = linkToSharedProgs("SHPF_weaponInfo_MaxAmmo"); + weaponInfo.IsSemiAuto = linkToSharedProgs("SHPF_weaponInfo_IsSemiAuto"); + weaponInfo.InventoryType = linkToSharedProgs("SHPF_weaponInfo_InventoryType"); + weaponInfo.FireTime = linkToSharedProgs("SHPF_weaponInfo_FireTime"); + weaponInfo.ClipSize = linkToSharedProgs("SHPF_weaponInfo_ClipSize"); + weaponInfo.Class = linkToSharedProgs("SHPF_weaponInfo_Class"); + weaponInfo.IsClipOnly = linkToSharedProgs("SHPF_weaponInfo_IsClipOnly"); + weaponInfo.IsDetonationTimed = linkToSharedProgs("SHPF_weaponInfo_IsDetonationTimed"); + + entityDef.GetString = linkToSharedProgs("SHPF_entityDef_GetString"); + entityDef.GetInteger = linkToSharedProgs("SHPF_entityDef_GetInteger"); + entityDef.GetBool = linkToSharedProgs("SHPF_entityDef_GetBool"); + entityDef.GetFloat = linkToSharedProgs("SHPF_entityDef_GetFloat"); + entityDef.GetVector = linkToSharedProgs("SHPF_entityDef_GetVector"); +} diff --git a/src/shared/api.qc b/src/shared/api.qc new file mode 100644 index 00000000..76405949 --- /dev/null +++ b/src/shared/api.qc @@ -0,0 +1,922 @@ +/* + * Copyright (c) 2016-2024 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +/* cvars library */ +string +SHPF_cvars_GetString(string cvarName) +{ + return cvar_string(cvarName); +} + +float +SHPF_cvars_GetFloat(string cvarName) +{ + return cvar(cvarName); +} + +int +SHPF_cvars_GetInteger(string cvarName) +{ + return (int)cvar(cvarName); +} + +bool +SHPF_cvars_GetBool(string cvarName) +{ + return (cvar(cvarName) > 0) ? (true) : (false); +} + +vector +SHPF_cvars_GetVector(string cvarName) +{ + return stov(cvar_string(cvarName)); +} + +void +SHPF_cvars_SetString(string cvarName, string setValue) +{ + cvar_set(cvarName, setValue); +} + +void +SHPF_cvars_SetInteger(string cvarName, int setValue) +{ + cvar_set(cvarName, itos(setValue)); +} + +void +SHPF_cvars_SetBool(string cvarName, bool setValue) +{ + cvar_set(cvarName, ftos(setValue)); +} + +void +SHPF_cvars_SetFloat(string cvarName, float setValue) +{ + cvar_set(cvarName, ftos(setValue)); +} + +void +SHPF_cvars_SetVector(string cvarName, vector setValue) +{ + cvar_set(cvarName, vtos(setValue)); +} + +/* decl library */ +string +SHPF_declManager_New(void) +{ + NSDict newDict = spawn(NSDict); + + /* not out of memory */ + if (newDict) { + /* assign it a new name, return */ + newDict.declclass = sprintf("NSDict_%x", num_for_edict(newDict)); + return (newDict.declclass); + } + + NSError("Unable to create decl"); + return (__NULL__); +} + +string +SHPF_declManager_GetString(string defName, string keyName) +{ + NSDict findDecl = (NSDict)find(world, ::declclass, defName); + + if (findDecl) { + return (findDecl.GetString(keyName)); + } + + NSError("Decl %S is not loaded.", defName); + return (__NULL__); +} + +int +SHPF_declManager_GetInteger(string defName, string keyName) +{ + NSDict findDecl = (NSDict)find(world, ::declclass, defName); + + if (findDecl) { + return (findDecl.GetInteger(keyName)); + } + + NSError("Decl %S is not loaded.", defName); + return (__NULL__); +} + +float +SHPF_declManager_GetFloat(string defName, string keyName) +{ + NSDict findDecl = (NSDict)find(world, ::declclass, defName); + + if (findDecl) { + return (findDecl.GetFloat(keyName)); + } + + NSError("Decl %S is not loaded.", defName); + return (__NULL__); +} + +bool +SHPF_declManager_GetBool(string defName, string keyName) +{ + NSDict findDecl = (NSDict)find(world, ::declclass, defName); + + if (findDecl) { + return (findDecl.GetBool(keyName)); + } + + NSError("Decl %S is not loaded.", defName); + return (__NULL__); +} + +vector +SHPF_declManager_GetVector(string defName, string keyName) +{ + NSDict findDecl = (NSDict)find(world, ::declclass, defName); + + if (findDecl) { + return (findDecl.GetVector(keyName)); + } + + NSError("Decl %S is not loaded.", defName); + return (__NULL__); +} + +void +SHPF_declManager_AddKey(string defName, string keyName, string setValue) +{ + NSDict findDecl = (NSDict)find(world, ::declclass, defName); + + if (findDecl) { + findDecl.AddKey(keyName, setValue); + return; + } + + NSError("Decl %S is not loaded.", defName); +} + +void +SHPF_declManager_RemoveKey(string defName, string keyName) +{ + NSDict findDecl = (NSDict)find(world, ::declclass, defName); + + if (findDecl) { + findDecl.RemoveKey(keyName); + return; + } + + NSError("Decl %S is not loaded.", defName); +} + +void +SHPF_declManager_Delete(string defName, string keyName) +{ + NSDict findDecl = (NSDict)find(world, ::declclass, defName); + + if (findDecl) { + remove(findDecl); + return; + } + + NSError("Decl %S is not loaded.", defName); +} + +/* ammo library */ +string +SHPF_ammo_NameForNum(int ammoIndex) +{ + return ammoNameForNum(ammoIndex); +} + +int +SHPF_ammo_NumForName(string ammoName) +{ + return ammoNumForName(ammoName); +} + +int +SHPF_ammo_MaxForName(string ammoName) +{ + return ammoMaxForName(ammoName); +} + +int +SHPF_ammo_MaxForNum(int ammoIndex) +{ + return ammoMaxForNum(ammoIndex); +} + +/* userinfo library */ +string +SHPF_userinfo_GetString(entity client, string keyName) +{ +#ifdef SERVER + return infokey(client, keyName); +#endif + +#ifdef CLIENT + return getplayerkeyvalue(client.entnum-1, keyName); +#endif +} + +int +SHPF_userinfo_GetInteger(entity client, string keyName) +{ + return stoi(SHPF_userinfo_GetString(client, keyName)); +} + +float +SHPF_userinfo_GetFloat(entity client, string keyName) +{ + return stof(SHPF_userinfo_GetString(client, keyName)); +} + +bool +SHPF_userinfo_GetBool(entity client, string keyName) +{ + return stof(SHPF_userinfo_GetString(client, keyName)) ? (true) : (false); +} + +vector +SHPF_userinfo_GetVector(entity client, string keyName) +{ + return stov(SHPF_userinfo_GetString(client, keyName)); +} + +void +SHPF_userinfo_SetString(entity client, string keyName, string setValue) +{ +#ifdef SERVER + forceinfokey(client, keyName, setValue); +#endif +} + +void +SHPF_userinfo_SetInteger(entity client, string keyName, int setValue) +{ + SHPF_userinfo_SetString(client, keyName, itos(setValue)); +} + +void +SHPF_userinfo_SetFloat(entity client, string keyName, float setValue) +{ + SHPF_userinfo_SetString(client, keyName, ftos(setValue)); +} + +void +SHPF_userinfo_SetBool(entity client, string keyName, bool setValue) +{ + SHPF_userinfo_SetString(client, keyName, ftos(setValue)); +} + +void +SHPF_userinfo_SetVector(entity client, string keyName, vector setValue) +{ + SHPF_userinfo_SetString(client, keyName, vtos(setValue)); +} + + +/* serverinfo library */ +string +SHPF_serverinfo_GetString(string serverKey) +{ + return serverkey(serverKey); +} + +float +SHPF_serverinfo_GetFloat(string serverKey) +{ + return serverkeyfloat(serverKey); +} + +int +SHPF_serverinfo_GetInteger(string serverKey) +{ + return (int)serverkeyfloat(serverKey); +} + +bool +SHPF_serverinfo_GetBool(string serverKey) +{ + return (serverkeyfloat(serverKey) > 0) ? (true) : (false); +} + +vector +SHPF_serverinfo_GetVector(string serverKey) +{ + return stov(serverkey(serverKey)); +} + +void +SHPF_serverinfo_SetString(string serverKey, string setValue) +{ +#ifdef SERVER + forceinfokey(world, serverKey, setValue); +#else +#endif +} + +void +SHPF_serverinfo_SetInteger(string serverKey, int setValue) +{ +#ifdef SERVER + forceinfokey(world, serverKey, itos(setValue)); +#else +#endif +} + +void +SHPF_serverinfo_SetBool(string serverKey, bool setValue) +{ +#ifdef SERVER + forceinfokey(world, serverKey, ftos(setValue)); +#else +#endif +} + +void +SHPF_serverinfo_SetFloat(string serverKey, float setValue) +{ +#ifdef SERVER + forceinfokey(world, serverKey, ftos(setValue)); +#else +#endif +} + +void +SHPF_serverinfo_SetVector(string serverKey, vector setValue) +{ +#ifdef SERVER + forceinfokey(world, serverKey, vtos(setValue)); +#else +#endif +} + + +/* team library */ + + +int +SHPF_teams_TeamCount(void) +{ + return SHPF_serverinfo_GetInteger("teams"); +} + +vector +SHPF_teams_Color(int teamID) +{ + return SHPF_serverinfo_GetVector(sprintf("teamcolor_%i", teamID)); +} + +string +SHPF_teams_Name(int teamID) +{ + return SHPF_serverinfo_GetString(sprintf("team_%i", teamID)); +} + +int +SHPF_teams_Score(int teamID) +{ + return SHPF_serverinfo_GetInteger(sprintf("teamscore_%i", teamID)); +} + +string +SHPF_teams_SpawnPoint(int teamID) +{ + return SHPF_serverinfo_GetString(sprintf("teamspawn_%i", teamID)); +} + +int +SHPF_teams_NumPlayers(int teamID) +{ + int countedPlayers = 0i; + +#ifdef CLIENT + for (int i = -1; i > -32; i--) { + int playerTeam = (int)getplayerkeyfloat(i, "*team"); + + if (playerTeam == teamID) { + countedPlayers++; + } + } +#else + for (entity teamPlayer = world; (teamPlayer = find(teamPlayer, ::classname, "player"));) { + if (teamPlayer.team == (float)teamID) { + countedPlayers++; + } + } +#endif + + return (countedPlayers); +} + +int +SHPF_teams_NumAlivePlayers(int teamID) +{ + int countedPlayers = 0i; + +#ifdef CLIENT + for (int i = -1; i > -32; i--) { + int playerTeam = (int)getplayerkeyfloat(i, "*team"); + bool playerDead = getplayerkeyfloat(i, "*dead"); + + if (playerTeam == teamID && playerDead == false) { + countedPlayers++; + } + } +#else + for (entity teamPlayer = world; (teamPlayer = find(teamPlayer, ::classname, "player"));) { + if (teamPlayer.team == (float)teamID && teamPlayer.health > 0) { + countedPlayers++; + } + } +#endif + + return (countedPlayers); +} + +entity +SHPF_teams_RandomPlayer(int teamID) +{ +#ifdef SERVER + int randomCounter = floor(random(1, (float)SHPF_teams_NumAlivePlayers(teamID))); + int countVal = 0i; + + for (entity teamPlayer = world; (teamPlayer = find(teamPlayer, ::classname, "player"));) { + if (teamPlayer.team == teamID) { + countVal++; + + if (countVal == randomCounter) { + return (teamPlayer); + } + } + } +#endif + + return __NULL__; +} + +int +SHPF_teams_NumDeadPlayers(int teamID) +{ + int countedPlayers = 0i; + +#ifdef CLIENT + for (int i = -1; i > -32; i--) { + int playerTeam = (int)getplayerkeyfloat(i, "*team"); + bool playerDead = getplayerkeyfloat(i, "*dead"); + + if (playerTeam == teamID && playerDead == true) { + countedPlayers++; + } + } +#else + for (entity a = world; (a = findfloat(a, ::identity, 1));) { + if (isPlayer(a)) { + NSClientPlayer pl = (NSClientPlayer)a; + if (pl.GetTeam() == (float)teamID && pl.IsAlive() == false) { + countedPlayers++; + } + } + } +#endif + + return (countedPlayers); +} + +int +SHPF_teams_TotalDeaths(int teamID) +{ + int deathCounter = 0i; + +#ifdef CLIENT + for (int i = -1; i > -32; i--) { + int playerTeam = (int)getplayerkeyfloat(i, "*team"); + + if (playerTeam == teamID) { + deathCounter += (int)getplayerkeyfloat(i, "*deaths"); + } + } +#else + for (entity a = world; (a = findfloat(a, ::identity, 1));) { + if (isPlayer(a)) { + NSClientPlayer pl = (NSClientPlayer)a; + if (pl.GetTeam() == (float)teamID) { + deathCounter += pl.deaths; + } + } + } +#endif + return (deathCounter); +} + +int +SHPF_teams_TotalFrags(int teamID) +{ + int fragCounter = 0i; + +#ifdef CLIENT + for (int i = -1; i > -32; i--) { + int playerTeam = (int)getplayerkeyfloat(i, "*team"); + + if (playerTeam == teamID) { + fragCounter += (int)getplayerkeyfloat(i, INFOKEY_P_FRAGS); + } + } +#else + for (entity a = world; (a = findfloat(a, ::identity, 1));) { + if (isPlayer(a)) { + NSClientPlayer pl = (NSClientPlayer)a; + if (pl.GetTeam() == (float)teamID) { + fragCounter += pl.frags; + } + } + } +#endif + + return (fragCounter); +} + +bool +SHPF_teams_Valid(int teamID) +{ + string teamName = SHPF_teams_Name(teamID); + + if (teamName == "") { + return (false); + } + + return (true); +} + +int +SHPF_teams_BestAutoJoinTeam(void) +{ + int sadTeam = 0i; + int sadCount = 1995i; /* unlikely high player number. */ + + /* maximum of 1000 teams. */ + for (int i = 0; i <= 1000; i++) { + /* gaps in team id setup can now act as divider, allowing which teams are auto-join. */ + if (SHPF_teams_Valid(i) == false) { + break; + } + + int playerCount = SHPF_teams_NumPlayers(i); + + if (playerCount < sadCount) { + sadCount = playerCount; + sadTeam = i; + } + } + + return (sadTeam); +} + +void +SHPF_teams_SetScore(int teamID, int setValue) +{ +#ifdef SERVER + SHPF_serverinfo_SetInteger(sprintf("teamscore_%i", teamID), setValue); +#else +#endif +} + +void +SHPF_teams_AddScore(int teamID, int addValue) +{ +#ifdef SERVER + int newValue = SHPF_teams_Score(teamID) + addValue; + SHPF_teams_SetScore(teamID, newValue); +#endif +} + +void +SHPF_teams_SetUp(int teamID, string teamTitle, vector teamColor, bool openTeam) +{ +#ifdef SERVER + int teamCount = 0i; + + if (!teamTitle || teamTitle == "") { + NSError("Team title cannot be empty."); + } + + if (teamID <= 0i) { + NSError("Team ID cannot be 0 or negative."); + } + + if (teamID > 1000i) { + NSError("Team ID cannot be over 1000. Reserved."); + } + + SHPF_serverinfo_SetString(sprintf("team_%i", teamID), teamTitle); + SHPF_serverinfo_SetString(sprintf("teamscore_%i", teamID), "0"); + SHPF_serverinfo_SetVector(sprintf("teamcolor_%i", teamID), teamColor / 255); + + if (openTeam) { + SHPF_serverinfo_SetString(sprintf("teamclosed_%i", teamID), ""); + } else { + SHPF_serverinfo_SetString(sprintf("teamclosed_%i", teamID), "1"); + } + + /* buh */ + for (teamCount = 0i; teamCount <= 1000; teamCount++) { + //printf("Checking validity of team %i\n", teamCount + 1i); + + if (SHPF_teams_Valid(teamCount + 1i) == false) { + break; + } + } + + //printf("SHPF_serverinfo_SetInteger %i\n", teamCount); + SHPF_serverinfo_SetInteger("teams", teamCount); +#else +#endif +} + +void +SHPF_teams_SetSpawnPoint(int teamID, string spawnPoint) +{ +#ifdef SERVER + SHPF_serverinfo_SetString(sprintf("teamspawn_%i", teamID), spawnPoint); +#else +#endif +} + +/* weaponInfo library */ + +/* required because we might need to look it up inside the +info for the primary attack mode. */ +static string +NSWeapon_GetPrimaryKeyValue(string weaponDef, string keyName) +{ + string fireInfo1 = EntityDef_GetKeyValue(weaponDef, "def_fireInfo"); + string defValue = EntityDef_GetKeyValue(weaponDef, keyName); + string fireInfoValue = EntityDef_GetKeyValue(fireInfo1, keyName); + + /* fireinfo takes priority */ + if (fireInfoValue) { + return (fireInfoValue); + } + + return (defValue); +} + +string +SHPF_weaponInfo_Type(string weaponDef) +{ + return ("unknown"); +} + +int +SHPF_weaponInfo_StartAmmo(string weaponDef) +{ + return (int)stof(EntityDef_GetKeyValue(weaponDef, "clipSize")); +} + +int +SHPF_weaponInfo_MaxAmmo(string weaponDef) +{ + string ammoType = NSWeapon_GetPrimaryKeyValue(weaponDef, "ammoType"); + return (ammoMaxForName(ammoType)); +} + +bool +SHPF_weaponInfo_IsSemiAuto(string weaponDef) +{ + return (bool)stof(NSWeapon_GetPrimaryKeyValue(weaponDef, "semiAuto")); +} + +string +SHPF_weaponInfo_InventoryType(string weaponDef) +{ + return ("item"); +} + +float +SHPF_weaponInfo_FireTime(string weaponDef) +{ + return stof(NSWeapon_GetPrimaryKeyValue(weaponDef, "fireRate")); +} + +int +SHPF_weaponInfo_ClipSize(string weaponDef) +{ + return (int)stoi(EntityDef_GetKeyValue(weaponDef, "clipSize")); +} + +string +SHPF_weaponInfo_Class(string weaponDef) +{ + return ("unknown"); +} + +bool +SHPF_weaponInfo_IsClipOnly(string weaponDef) +{ + int clipSize = (int)stoi(EntityDef_GetKeyValue(weaponDef, "clipSize")); + string ammoType = NSWeapon_GetPrimaryKeyValue(weaponDef, "ammoType"); + + /* no ammo type... */ + if (!ammoType) { + /* but a clip is defined */ + if (clipSize > 0i) { + return (true); + } + } + return (false); +} + +bool +SHPF_weaponInfo_IsDetonationTimed(string weaponDef) +{ + string projectileDef = NSWeapon_GetPrimaryKeyValue(weaponDef, "def_projectile"); + bool isFused = (bool)stof(EntityDef_GetKeyValue(projectileDef, "detonate_on_fuse")); + return (isFused); +} + + +NSEntity +spawnClass(string className, vector desiredPos) +{ + NSEntity newEntity = __NULL__; + +#ifdef SERVER + newEntity = Entity_CreateClass(className); + + /* That class didn't exist, so let's take the base Nuclide one */ + if (!newEntity) { + newEntity = Entity_CreateClass("NSEntity"); + } + + /* OOM. It's over. */ + if (!newEntity) { + return (__NULL__); + } + + newEntity.classname = className; + newEntity.Spawn(); + newEntity.SetOrigin(desiredPos); +#endif + + return (newEntity); +} + +#ifdef SERVER +bool +changeClass(entity target, string className) +{ + /* hijack that decl. you don't to mess with this. */ + if (target.flags & FL_CLIENT) { + if (className == "spectator") { + NSClientPlayer theClient = (NSClientPlayer)target; + changeClass(theClient, "player"); + theClient.MakeTempSpectator(); + theClient.team = TEAM_SPECTATOR; + return (true); + } + } + + return EntityDef_SwitchClass((NSEntity)target, className) ? (true) : (false); +} +#endif + +void +sendInput(entity target, string inputName, string dataString, entity activator) +{ + NSEntity targetEntity = (NSEntity)target; +#ifdef SERVER + targetEntity.Input(activator, inputName, dataString); +#endif +} + +/* helper functions */ +bool +isAI(entity entityToCheck) +{ + if (entityToCheck.flags & FL_MONSTER) { + return (true); + } + + return (false); +} + +bool +isAlive(entity entityToCheck) +{ +#ifdef SERVER + if (entityToCheck.takedamage != DAMAGE_NO) { + NSSurfacePropEntity livingEnt = (NSSurfacePropEntity)entityToCheck; + return livingEnt.IsAlive(); + } +#endif + + return (false); +} + +bool +isGodMode(entity entityToCheck) +{ + if (entityToCheck.flags & FL_GODMODE) { + return (true); + } + + return (false); +} + +bool +isClient(entity entityToCheck) +{ + return (entityToCheck.flags & FL_CLIENT) ? (true) : (false); +} + +bool +isPlayer(entity entityToCheck) +{ + if (isClient(entityToCheck)) { + NSClient pl = (NSClient)entityToCheck; + + return pl.IsPlayer(); + } + + return (false); +} + +bool +isSentient(entity entityToCheck) +{ + if (isAI(entityToCheck) || isPlayer(entityToCheck)) { + return (true); + } + + return (false); +} + +bool +isBot(entity entityToCheck) +{ +#ifdef SERVER + return (clienttype(entityToCheck) == CLIENTTYPE_BOT) ? (true) : (false); +#else + return (false); +#endif +} + +bool +isWeapon(entity entityToCheck) +{ + return (entityToCheck._isWeapon) ? (true) : (false); +} + +bool +isItem(entity entityToCheck) +{ + return (entityToCheck._isItem) ? (true) : (false); +} + +string +SHPF_entityDef_GetString(string declName, string keyName) +{ + return EntityDef_GetKeyValue(declName, keyName); +} + +int +SHPF_entityDef_GetInteger(string declName, string keyName) +{ + return (int)stoi(SHPF_entityDef_GetString(declName, keyName)); +} + +bool +SHPF_entityDef_GetBool(string declName, string keyName) +{ + + return stof(SHPF_entityDef_GetString(declName, keyName)) ? (true) : (false); +} + +float +SHPF_entityDef_GetFloat(string declName, string keyName) +{ + + return stof(SHPF_entityDef_GetString(declName, keyName)); +} + +vector +SHPF_entityDef_GetVector(string declName, string keyName) +{ + return stov(SHPF_entityDef_GetString(declName, keyName)); +} diff --git a/src/shared/cloader.qc b/src/shared/cloader.qc index ac37d4a9..5be51839 100644 --- a/src/shared/cloader.qc +++ b/src/shared/cloader.qc @@ -19,7 +19,8 @@ #endif string g_constIndex[MAX_CONSTANTS_ID]; -static int g_constCount; +static int g_constCount; +const string g_constantsFile = "scripts/constants.txt"; void Constants_Init(void) @@ -28,20 +29,20 @@ Constants_Init(void) string tempString; int arguments = 0i; int indexCount = 0i; - - InitStart(); - - g_constCount = 0i; + + InitStart(); + + g_constCount = 0i; if (!g_hashConstants) { g_hashConstants = hash_createtab(2, HASH_ADD); } - constFile = fopen("scripts/constants.txt", FILE_READ); + constFile = fopen(g_constantsFile, FILE_READ); if (constFile < 0) { - NSError("Missing file scripts/constants.txt"); - InitEnd(); + NSWarning("No constants, missing %S", g_constantsFile); + InitEnd(); return; } @@ -54,28 +55,30 @@ Constants_Init(void) /* sanity bounds check */ if (!Constants_Add(argv(0), argv(1))) { - InitEnd(); + fclose(constFile); + InitEnd(); return; } } - - InitEnd(); + + fclose(constFile); + InitEnd(); } - -bool -Constants_Add(string constantName, string constantValue) -{ + +bool +Constants_Add(string constantName, string constantValue) +{ /* sanity bounds check */ if (g_constCount == MAX_CONSTANTS_ID) { NSError("Hit maximum number of %d constants.", MAX_CONSTANTS_ID); return (false); } - + g_constIndex[g_constCount] = constantValue; hash_add(g_hashConstants, constantName, g_constCount); g_constCount++; - return (true); -} + return (true); +} string Constants_LookUp(string constName, string returnValue) @@ -83,8 +86,9 @@ Constants_LookUp(string constName, string returnValue) int constIndex = -1i; /* only if we're prefixed */ - if (substring(constName, 0, 1) == "$") + if (substring(constName, 0, 1) == "$") { constIndex = hash_get(g_hashConstants, substring(constName, 1, -1), -1i); + } return (constIndex == -1i) ? returnValue : g_constIndex[constIndex]; } diff --git a/src/shared/decalgroups.qc b/src/shared/decalgroups.qc index 854afb13..49325ce8 100644 --- a/src/shared/decalgroups.qc +++ b/src/shared/decalgroups.qc @@ -109,6 +109,9 @@ DecalGroups_Parse(string line) } } + +const string g_decalGroupFile = "scripts/decals.txt"; + void DecalGroups_Init(void) { @@ -123,21 +126,32 @@ DecalGroups_Init(void) g_hashdecalgroup = hash_createtab(2, EV_STRING | HASH_REPLACE); } - fh = fopen("scripts/decals.txt", FILE_READ); + fh = fopen(g_decalGroupFile, FILE_READ); + if (fh < 0) { - NSError("Missing file scripts/decals.txt"); + NSWarning("No groups, no %S", g_decalGroupFile); InitEnd(); return; } #ifdef CLIENT + int dgMemSize; + /* count content */ while ((line = fgets(fh))) { DecalGroups_CountLine(line); } /* alocate our stuff */ - g_decalgroup = (decalGroup_t *)memalloc(sizeof(decalGroup_t) * g_decalgroup_count); + dgMemSize = sizeof(decalGroup_t) * g_decalgroup_count; + g_decalgroup = (decalGroup_t *)memalloc(dgMemSize); + + if (!g_decalgroup) { + NSError("Memory allocation failed for %i bytes.", dgMemSize); + g_decalgroup_count = 0; + InitEnd(); + return; + } /* Defaults */ for (int i = 0; i < g_decalgroup_count; i++) { diff --git a/src/shared/defs.h b/src/shared/defs.h index c301f04d..592e8837 100644 --- a/src/shared/defs.h +++ b/src/shared/defs.h @@ -46,12 +46,15 @@ typedef entity id; #define NSENTITY_READENTITY(x, y) \ { \ local x x ##_e = ( x )self;\ + local float x ##receivedFlags;\ if (y == true) { \ self.classname = strcat("spawnfunc_", #x); \ callfunction(self.classname); \ } \ - x ##_e.ReceiveEntity( y, readfloat() );\ + x ##receivedFlags = readfloat();\ + x ##_e.ReceiveEntity( y, x ##receivedFlags );\ x ##_e.Relink();\ + x ##_e._ReceiveComplete( y, x ##receivedFlags );\ } #else @@ -65,8 +68,6 @@ typedef entity id; #define ATTR_CHANGED(x) (x ##_net != x) #define VEC_CHANGED(x,y) (x ##_net[y] != x[y]) -#define STRING_SET(x) ((x != __NULL__) && (x != "")) - #ifndef MAX_AMMO_TYPES #define MAX_AMMO_TYPES 16i #endif @@ -101,6 +102,7 @@ string __fullspawndata; #include "NSTimer.h" #include "NSRenderableEntity.h" #include "NSSurfacePropEntity.h" +#include "NSRagdoll.h" #include "NSMoverEntity.h" #include "NSPhysicsConstraint.h" #include "NSPhysicsEntity.h" @@ -118,12 +120,14 @@ string __fullspawndata; #include "NSProjectile.h" #include "NSSpraylogo.h" #include "NSPortal.h" +#include "NSSound.h" #include "NSDebris.h" #include "../xr/defs.h" #include "../botlib/NSBot.h" #include "NSClient.h" #include "NSClientSpectator.h" +#include "pmove.h" #include "NSClientPlayer.h" #include "NSVehicle.h" @@ -132,10 +136,7 @@ string __fullspawndata; #include "damage.h" #include "flags.h" #include "entities.h" -#include "events.h" -#include "flags.h" #include "hitmesh.h" -#include "pmove.h" #include "memory.h" #include "platform.h" #include "propdata.h" @@ -162,24 +163,7 @@ const vector VEC_HULL_MAX = [16,16,36]; const vector VEC_CHULL_MIN = [-16,-16,-18]; const vector VEC_CHULL_MAX = [16,16,18]; -// Actually used by input_button etc. -#define INPUT_BUTTON0 0x00000001 /* attack 1*/ -#define INPUT_BUTTON2 0x00000002 /* jumping */ -#define INPUT_BUTTON3 0x00000004 /* prone */ -#define INPUT_BUTTON4 0x00000008 /* reload */ -#define INPUT_BUTTON5 0x00000010 /* secondary */ -#define INPUT_BUTTON6 0x00000020 /* use */ -#define INPUT_BUTTON7 0x00000040 /* reserved */ -#define INPUT_BUTTON8 0x00000080 /* crouching */ - -#define INPUT_PRIMARY INPUT_BUTTON0 -#define INPUT_JUMP INPUT_BUTTON2 -#define INPUT_PRONE INPUT_BUTTON3 -#define INPUT_RELOAD INPUT_BUTTON4 -#define INPUT_SECONDARY INPUT_BUTTON6 -#define INPUT_USE INPUT_BUTTON5 /* This can NEVER change. Engine hard-coded. */ -#define INPUT_SPRINT INPUT_BUTTON7 -#define INPUT_CROUCH INPUT_BUTTON8 +#include "input.h" /* sendflags */ #define UPDATE_ALL 16777215 @@ -200,6 +184,10 @@ enumflags .float teleport_time; .vector basevelocity; .float gflags; +.float identity; + +.bool _isWeapon; +.bool _isItem; void Empty(void) @@ -355,7 +343,6 @@ memalloc(int size) return prior(size); } -.float identity; .float removed; __wrap void remove(entity target) @@ -431,7 +418,7 @@ unpackStringCommand(string commandString) } /* is this supposed to be read from a skill cvar? */ if (substring(commandString, 0, 5) == "cvar:") { - return cvar_string(substring(commandString, 5, -1), ""); + return cvar_string(substring(commandString, 5, -1)); } #endif @@ -613,16 +600,6 @@ Route_GetJumpVelocity(vector vecFrom, vector vecTo, float flGravMod) return vecJump; } -bool -fileExists(string filePath) -{ - if (filePath != "") /* not empty */ - if not(whichpack(filePath)) /* not present on disk */ - return false; - - return true; -} - void DebugBox(vector absPos, vector minSize, vector maxSize, vector boxColor, float boxAlpha) { diff --git a/src/shared/entities.h b/src/shared/entities.h index df24f028..0fe8e5f6 100644 --- a/src/shared/entities.h +++ b/src/shared/entities.h @@ -36,6 +36,7 @@ typedef enum { ENT_NONE = 0, /**< invalid, but reserved. */ ENT_ENTITY, /**< of type NSEntity */ + ENT_SOUND, /**< of type NSSound */ ENT_PMOVEVARS, /**< of type NSPMoveVars */ ENT_ENTITYRENDERABLE, /**< of type NSRenderableEntity */ ENT_ENTITYPROJECTILE, /**< of type NSProjectile */ @@ -47,6 +48,7 @@ typedef enum ENT_PLAYER, /**< of type NSClientPlayer */ ENT_ITEM, /**< of type NSItem */ ENT_WEAPON, /**< of type NSWeapon */ + ENT_RAGDOLL, /**< of type NSRagdoll */ ENT_SPECTATOR, /**< of type NSClientSpectator */ ENT_PORTAL, /**< of type NSPortal */ ENT_AMBIENTSOUND, /**< of type ambient_generic */ diff --git a/src/shared/entityDef.h b/src/shared/entityDef.h index 7de60fb8..4b51b54b 100644 --- a/src/shared/entityDef.h +++ b/src/shared/entityDef.h @@ -41,7 +41,7 @@ and populate it with key/value pairs. # Overview -Using this example definition, we can re-invent func_illusionary using an already existing entity class (func_wall) and making it non-solid: +Using this example definition, we can re-invent func_illusionary using an already existing entity class (func_wall), making it non-solid: ``` entityDef func_illusionary { @@ -50,7 +50,7 @@ entityDef func_illusionary { } ``` -We also have features exclusive to our entityDef format. In the following example, you can change the `body` key equals `1`, the switch will `skin` to id `4`. You can as many conditions as you like. +We also have features exclusive to our entityDef format. In the following example, when the`body` key equals `1`, it will switch `skin` to id `4`. You can have as many conditions as you like. ``` entityDef foobar { @@ -62,10 +62,10 @@ entityDef foobar { } ``` -Will allow developers to configure other fields when certain +It essentially allows developers to configure other fields when certain conditions are met. -This is also expanded to include model event callbacks to the tried +Another feature exclusive to our entityDef spec is how we can tie model event callbacks to the tried and true I/O system: ``` @@ -78,10 +78,13 @@ entityDef foobar { } ``` +This way, an animation that is played by a weapon or a monster can call back +to in-game events without you having to dig into the source code. + # See Also -- [1] http://www.teamfortress.com/tfii/mc2mapc.html -- [2] http://icculus.org/~marco/notmine/id-dev/www.iddevnet.com/doom3/entitydefs.html +- [1] http://icculus.org/~marco/notmine/id-dev/www.iddevnet.com/doom3/entitydefs.html +- [2] http://www.teamfortress.com/tfii/mc2mapc.html @{ @@ -120,8 +123,8 @@ typedef struct void EntityDef_Init(void); void EntityDef_DebugList(void); string EntityDef_GetKeyValue(string, string); -float EntityDef_NetIDFromName(string); -string EntityDef_NameFromNetID(float); +int EntityDef_NetIDFromName(string); +string EntityDef_NameFromNetID(int); int EntityDef_IDFromName(string); string EntityDef_GetSpawnData(int); bool EntityDef_HasSpawnClass(string className); diff --git a/src/shared/entityDef.qc b/src/shared/entityDef.qc index a72b846e..fce6c5a3 100644 --- a/src/shared/entityDef.qc +++ b/src/shared/entityDef.qc @@ -268,8 +268,6 @@ EntityDef_CheckCondition(NSEntity target, int id, string keyWord, float tweakCon tmp1 = stof(keyValue); tmp2 = stof(value); - print(sprintf("%d & %d\n", tmp1, tmp2)); - if (key == keyWord && tmp2 & tmp1) return true; break; @@ -393,8 +391,9 @@ EntityDef_PrepareEntity(entity target, int id) for (int i = 1; i < (spawnWords - 1); i+= 2) { /* ignore this, always */ - if (argv(i) != "classname") + if (argv(i) != "classname") { targetEnt.SpawnKey(argv(i), argv(i+1)); + } } /* now after everything else is done, check our entityDef tweaks */ @@ -410,7 +409,7 @@ EntityDef_PrepareEntity(entity target, int id) string keyValue = argv(2); /* iterate through a bunch of different data to check our condition */ - if (EntityDef_CheckCondition(target, id, keyWord, tweakCondition, keyValue)) { + if (EntityDef_CheckCondition((NSEntity)target, id, keyWord, tweakCondition, keyValue)) { int tweakGroups = tokenizebyseparator(g_entDefTable[id].tweakKeys, ";"); //print(sprintf("%S passed the check\n", keyWord)); @@ -432,16 +431,6 @@ EntityDef_PrepareEntity(entity target, int id) /* retokenize */ tweakGroups = tokenizebyseparator(g_entDefTable[id].tweakKeys, ";"); } - - print("\n"); - print("\n"); - print("\n"); - print("\n"); - print(targetEnt.m_strSpawnData); - print("\n"); - print("\n"); - print("\n"); - print("\n"); } /* retokenize our condition */ @@ -457,8 +446,7 @@ EntityDef_PrepareEntity(entity target, int id) targetEnt.classname = g_entDefTable[id].entClass; targetEnt.entityDefID = EntityDef_NetIDFromName(targetEnt.classname); - targetEnt.Spawned(); - targetEnt.Respawn(); + targetEnt.Spawn(); } g_lastSpawnData = ""; @@ -555,7 +543,6 @@ NSEntity EntityDef_SwitchClass(NSEntity target, string className) { NSEntity returnEntity = __NULL__; - float oldTeam = target.team; g_lastSpawnData = target.m_strSpawnData; for (int i = 0i; i < g_entDefCount; i++) { @@ -566,7 +553,6 @@ EntityDef_SwitchClass(NSEntity target, string className) NSLog("Spawning eDef %S", className); returnEntity = EntityDef_PrepareEntity(target, i); - returnEntity.team = oldTeam; return (returnEntity); } } @@ -649,11 +635,18 @@ EntityDef_DebugList(void) } } -float +int +ourCRC(string name) +{ + int crcValue = (int)(stoh(digest_hex("CRC16", strtolower(name)))); + return (crcValue); +} + +int EntityDef_NetIDFromName(string defName) { #if 1 - return crc16(true, defName); + return ourCRC(defName); #else if (defName) { for (int i = 0i; i < g_entDefCount; i++) { @@ -682,10 +675,10 @@ EntityDef_IDFromName(string defName) } string -EntityDef_NameFromNetID(float defNum) +EntityDef_NameFromNetID(int defNum) { for (int i = 0i; i < g_entDefCount; i++) { - int checkSum = crc16(true, g_entDefTable[i].entClass); + int checkSum = ourCRC(g_entDefTable[i].entClass); if (checkSum == defNum) { return (g_entDefTable[i].entClass); @@ -695,7 +688,6 @@ EntityDef_NameFromNetID(float defNum) return ""; } - string EntityDef_GetSpawnData(int defNum) { diff --git a/src/shared/fteextensions.qc b/src/shared/fteextensions.qc index 6c03b4eb..f1402fce 100644 --- a/src/shared/fteextensions.qc +++ b/src/shared/fteextensions.qc @@ -1,3841 +1,3841 @@ -/* -This file was generated by FTE Quake 6278M, dated Jun 27 2022. -This file can be regenerated by issuing the following command: -pr_dumpplatform -(Use the -help arg for a list of available args) -*/ -#pragma noref 1 -//#pragma flag enable logicops -#pragma warning error Q101 /*too many parms. The vanilla qcc didn't validate properly, hence why fteqcc normally treats it as a warning.*/ -#pragma warning error Q105 /*too few parms. The vanilla qcc didn't validate properly, hence why fteqcc normally treats it as a warning.*/ -#pragma warning error Q106 /*assignment to constant/lvalue. Define them as var if you want to initialise something.*/ -#pragma warning error Q208 /*system crc unknown. Compatibility goes out of the window if you disable this.*/ -#pragma warning enable F301 /*non-utf-8 strings. Think of the foreigners! Also think of text editors that insist on screwing up your char encodings.*/ -#pragma warning enable F302 /*uninitialised locals. They usually default to 0 in qc (except in recursive functions), but its still probably a bug*/ -#if !defined(CSQC) && !defined(NQSSQC) && !defined(QWSSQC)&& !defined(MENU) - #ifdef QUAKEWORLD - #define QWSSQC - #else - #define NQSSQC - #endif -#endif -#if !defined(SSQC) && (defined(QWSSQC) || defined(NQSSQC)) - #define SSQC -#endif -#if defined(CSQC) || defined(MENU) - #define DEP_CSQC DEP -#else - #define DEP_CSQC __deprecated("Use CSQC for this") -#endif -#ifndef DEP - #define DEP __deprecated //predefine this if you want to avoid our deprecation warnings. -#endif -#ifndef FTEDEP - #define FTEDEP(reason) //for symbols deprecated in FTE that may still be useful/required for other engines -#endif -#define BX_COLOREDTEXT -#define DP_CON_SET /* The 'set' console command exists, and can be used to create/set cvars. */ -#define DP_CON_SETA /* The 'seta' console command exists, like the 'set' command, but also marks the cvar for archiving, allowing it to be written into the user's config. Use this command in your default.cfg file. */ -#define DP_CSQC_ROTATEMOVES -#define DP_EF_ADDITIVE -#define DP_ENT_ALPHA -#define DP_EF_BLUE -#define DP_EF_FULLBRIGHT -#define DP_EF_NODEPTHTEST -#define DP_EF_NODRAW -#define DP_EF_NOGUNBOB -#define DP_EF_NOSHADOW -#define DP_EF_RED -#define DP_ENT_COLORMOD -#define DP_ENT_CUSTOMCOLORMAP -#define DP_ENT_EXTERIORMODELTOCLIENT -#define DP_ENT_SCALE -#define DP_ENT_TRAILEFFECTNUM /* self.traileffectnum=particleeffectnum("myeffectname"); can be used to attach a particle trail to the given server entity. This is equivelent to calling trailparticles each frame. */ -#define DP_ENT_VIEWMODEL -#define DP_GECKO_SUPPORT -#define DP_GFX_FONTS -#define DP_GFX_QUAKE3MODELTAGS -#define DP_GFX_SKINFILES -#define DP_GFX_SKYBOX -#define DP_HALFLIFE_MAP -#define DP_HALFLIFE_MAP_CVAR -#define DP_INPUTBUTTONS -#define DP_LIGHTSTYLE_STATICVALUE -#define DP_LITSUPPORT -#define DP_MONSTERWALK /* MOVETYPE_WALK is valid on non-player entities. Note that only players receive acceleration etc in line with none/bounce/fly/noclip movetypes on the player, thus you will have to provide your own accelerations (incluing gravity) yourself. */ -#define DP_MOVETYPEBOUNCEMISSILE -#define DP_MOVETYPEFOLLOW -#define DP_QC_ASINACOSATANATAN2TAN -#define DP_QC_CHANGEPITCH -#define DP_QC_COPYENTITY -#define DP_QC_CRC16 -#define DP_QC_CVAR_DEFSTRING -#define DP_QC_CVAR_STRING -#define DP_QC_CVAR_TYPE -#define DP_QC_DIGEST_SHA256 -#define DP_QC_EDICT_NUM -#define DP_QC_ENTITYDATA -#define DP_QC_ETOS -#define DP_QC_FINDCHAIN -#define DP_QC_FINDCHAINFLOAT -#define DP_QC_FINDFLAGS -#define DP_QC_FINDCHAINFLAGS -#define DP_QC_FINDFLOAT -#define DP_QC_FS_SEARCH -#define DP_QC_FS_SEARCH_PACKFILE -#define DP_QC_GETLIGHT -#define DP_QC_GETSURFACE -#define DP_QC_GETSURFACEPOINTATTRIBUTE -#define DP_QC_GETTAGINFO -#define DP_QC_I18N /* Specifies that the engine uses $MODULE.dat.$LANG.po files that translates the dotranslate_* globals on load - these are usually created via the _("foo") qcc intrinsic. */ -#define DP_QC_MINMAXBOUND -#define DP_QC_MULTIPLETEMPSTRINGS /* Superseded by DP_QC_UNLIMITEDTEMPSTRINGS. Functions that return a temporary string will not overwrite/destroy previous temporary strings until at least 16 strings are returned (or control returns to the engine). */ -#define DP_QC_RANDOMVEC -#define DP_QC_RENDER_SCENE /* clearscene+addentity+setviewprop+renderscene+setmodel are available to menuqc. WARNING: DP advertises this extension without actually supporting it, FTE does actually support it. */ -#define DP_QC_SINCOSSQRTPOW -#define DP_QC_SPRINTF /* Provides the sprintf builtin, which allows for rich formatting along the lines of C's function with the same name. Not to be confused with QC's sprint builtin. */ -#define DP_QC_STRFTIME -#define DP_QC_STRING_CASE_FUNCTIONS -#define DP_QC_STRINGBUFFERS -#define DP_QC_STRINGCOLORFUNCTIONS -#define DP_QC_STRREPLACE -#define DP_QC_TOKENIZEBYSEPARATOR -#define DP_QC_TRACEBOX -#define DP_QC_TRACETOSS -#define DP_QC_TRACE_MOVETYPE_HITMODEL -#define DP_QC_TRACE_MOVETYPE_WORLDONLY -#define DP_QC_TRACE_MOVETYPES -#define DP_QC_UNLIMITEDTEMPSTRINGS /* Supersedes DP_QC_MULTIPLETEMPSTRINGS, superseded by FTE_QC_PERSISTENTTEMPSTRINGS. Specifies that all temp strings will be valid at least until the QCVM returns. */ -#define DP_QC_URI_ESCAPE -#define DP_QC_URI_GET -#define DP_QC_URI_POST -#define DP_QC_VECTOANGLES_WITH_ROLL -#define DP_QC_VECTORVECTORS -#define DP_QC_WHICHPACK -#define DP_QUAKE2_MODEL -#define DP_QUAKE2_SPRITE -#define DP_QUAKE3_MAP -#define DP_QUAKE3_MODEL -#define DP_REGISTERCVAR -#define DP_SND_SOUND7_WIP2 -#define DP_SND_STEREOWAV -#define DP_SND_OGGVORBIS -#define DP_SOLIDCORPSE -#define DP_SPRITE32 -#define DP_SV_BOTCLIENT -#define DP_SV_CLIENTCAMERA /* Works like svc_setview except also handles pvs. */ -#define DP_SV_CLIENTCOLORS /* Provided only for compatibility with DP. */ -#define DP_SV_CLIENTNAME /* Provided only for compatibility with DP. */ -#define DP_SV_CUSTOMIZEENTITYFORCLIENT /* Deprecated feature for compat with DP. Can be slow, incompatible with splitscreen, usually malfunctions with mvds. */ -#define DP_SV_DRAWONLYTOCLIENT -#define DP_SV_DROPCLIENT /* Equivelent to quakeworld's stuffcmd(self,"disconnect\n"); hack */ -#define DP_SV_EFFECT -#define DP_SV_EXTERIORMODELFORCLIENT -#define DP_SV_NODRAWTOCLIENT -#define DP_SV_PLAYERPHYSICS /* Allows reworking parts of NQ player physics. USE AT OWN RISK - this necessitates NQ physics and is thus guarenteed to break prediction. */ -#define DP_SV_POINTSOUND -#define DP_SV_PRECACHEANYTIME /* Specifies that the various precache builtins can be called at any time. WARNING: precaches are sent reliably while sound events, modelindexes, and particle events are not. This can mean sounds and particles might not work the first time around, or models may take a while to appear (after the reliables are received and the model is loaded from disk). Always attempt to precache a little in advance in order to reduce these issues (preferably at the start of the map...) */ -#define DP_SV_PRINT /* Says that the print builtin can be used from nqssqc (as well as just csqc), bypassing the developer cvar issues. */ -#define DP_SV_ROTATINGBMODEL /* Engines that support this support avelocity on MOVETYPE_PUSH entities, pushing entities out of the way as needed. */ -#define DP_SV_SETCOLOR -#define DP_SV_SHUTDOWN -#define DP_SV_SPAWNFUNC_PREFIX -#define DP_SV_WRITEPICTURE -#define DP_SV_WRITEUNTERMINATEDSTRING -#define DP_TE_BLOOD -#define DP_TE_CUSTOMFLASH -#define DP_TE_EXPLOSIONRGB -#define DP_TE_PARTICLECUBE -#define DP_TE_PARTICLERAIN -#define DP_TE_PARTICLESNOW -#define DP_TE_SMALLFLASH -#define DP_TE_SPARK -#define DP_TE_STANDARDEFFECTBUILTINS -#define DP_VIEWZOOM -#define EXT_BITSHIFT -#define EXT_CSQC -#define EXT_CSQC_SHARED -#define EXT_DIMENSION_VISIBILITY -#define EXT_DIMENSION_PHYSICS -#define EXT_DIMENSION_GHOST -#define FRIK_FILE -#define FTE_CALLTIMEOFDAY /* Replication of mvdsv functionality (call calltimeofday to cause 'timeofday' to be called, with arguments that can be saved off to a global). Generally strftime is simpler to use. */ -#define FTE_CSQC_ALTCONSOLES /* The engine tracks multiple consoles. These may or may not be directly visible to the user. */ -#define FTE_CSQC_BASEFRAME /* Specifies that .basebone, .baseframe2, .baselerpfrac, baseframe1time, etc exist in csqc. These fields affect all bones in the entity's model with a lower index than the .basebone field, allowing you to give separate control to the legs of a skeletal model, without affecting the torso animations. */ -#define FTE_CSQC_HALFLIFE_MODELS -#define FTE_CSQC_SERVERBROWSER /* Provides builtins to query the engine's serverbrowser servers list from ssqc. Note that these builtins are always available in menuqc. */ -#define FTE_CSQC_SKELETONOBJECTS /* Provides container objects for skeletal bone data, which can be modified on a per bone basis if needed. This allows you to dynamically generate animations (or just blend them with greater customisation) instead of being limited to a single animation or two. */ -#define FTE_CSQC_RAWIMAGES /* Provides raw rgba image access to csqc. With this, the csprogs can read textures into qc-accessible memory, modify it, and then upload it to the renderer. */ -#define FTE_CSQC_RENDERTARGETS /* VF_RT_DESTCOLOUR exists and can be used to redirect any rendering to a texture instead of the screen. */ -#define FTE_CSQC_REVERB /* Specifies that the mod can create custom reverb effects. Whether they will actually be used or not depends upon the sound driver. */ -#define FTE_CSQC_WINDOWCAPTION /* Provides csqc with the ability to change the window caption as displayed when running windowed or in the task bar when switched out. */ -#define FTE_ENT_SKIN_CONTENTS /* self.skin = CONTENTS_WATER; makes a brush entity into water. use -16 for a ladder. */ -#define FTE_ENT_UNIQUESPAWNID -#define FTE_EXTENDEDTEXTCODES -#define FTE_FORCESHADER /* Allows csqc to override shaders on models with an explicitly named replacement. Also allows you to define shaders with a fallback if it does not exist on disk. */ -#define FTE_FORCEINFOKEY /* Provides an easy way to change a user's userinfo from the server. */ -#define FTE_GFX_QUAKE3SHADERS /* specifies that the engine has full support for vanilla quake3 shaders */ -#define FTE_GFX_REMAPSHADER /* With the raw power of stuffcmds, the r_remapshader console command is exposed! This mystical command can be used to remap any shader to another. Remapped shaders that specify $diffuse etc in some form will inherit the textures implied by the surface. */ -#define FTE_GFX_IQM_HITMESH /* Supports hitmesh iqm extensions. Also supports geomsets and embedded events. */ -#define FTE_GFX_MODELEVENTS /* Provides a query for per-animation events in model files, including from progs/foo.mdl.events files. */ -#define FTE_ISBACKBUFFERED /* Allows you to check if a client has too many reliable messages pending. */ -#define FTE_MEMALLOC /* Allows dynamically allocating memory. Use pointers to access this memory. Memory will not be saved into saved games. */ -#define FTE_MEDIA_CIN /* playfilm command supports q2 cin files. */ -#define FTE_MEDIA_ROQ /* playfilm command supports q3 roq files. */ -#define FTE_MULTIPROGS /* Multiple progs.dat files can be loaded inside the same qcvm. Insert new ones with addprogs inside the 'init' function, and use externvalue+externset to rewrite globals (and hook functions) to link them together. Note that the result is generally not very clean unless you carefully design for it beforehand. */ -#define FTE_MULTITHREADED /* Faux multithreading, allowing multiple contexts to run in sequence. */ -#define FTE_MVD_PLAYERSTATS /* In csqc, getplayerstat can be used to query any player's stats when playing back MVDs. isdemo will return 2 in this case. */ -#define FTE_PART_SCRIPT /* Specifies that the r_particledesc cvar can be used to select a list of particle effects to load from particles/foo.cfg, the format of which is documented elsewhere. */ -#define FTE_PART_NAMESPACES /* Specifies that the engine can use foo.bar to load effect foo from particle description bar. When used via ssqc, this should cause the client to download whatever effects as needed. */ -#define FTE_PART_NAMESPACE_EFFECTINFO /* Specifies that effectinfo.bar can load effects from effectinfo.txt for DP compatibility. */ -#define FTE_PEXT_SETVIEW /* NQ's svc_setview works correctly even in quakeworld */ -#define FTE_PEXT_LIGHTSTYLECOL -#define FTE_PEXT_VIEW2 -#define FTE_PEXT_FATNESS -#define FTE_PEXT_TE_BULLET -#define FTE_PEXT_FLOATCOORDS -#define FTE_PEXT_Q2BSP /* Specifies that the client supports q2bsps. */ -#define FTE_PEXT_Q3BSP /* Specifies that the client supports q3bsps. */ -#define FTE_HEXEN2 -#define FTE_PEXT_SPAWNSTATIC -#define FTE_PEXT_CUSTOMTENTS -#define FTE_PEXT_256PACKETENTITIES /* Specifies that the client is not limited to vanilla's limit of only 64 ents visible at once. */ -#define FTE_QC_BASEFRAME /* Specifies that .basebone and .baseframe exist in ssqc. These fields affect all bones in the entity's model with a lower index than the .basebone field, allowing you to give separate control to the legs of a skeletal model, without affecting the torso animations, from ssqc. */ -#define FTE_QC_FILE_BINARY /* Extends FRIK_FILE with binary read+write, as well as allowing seeking. Requires pointers. */ -#define FTE_QC_CHANGELEVEL_HUB /* Adds an extra argument to changelevel which is carried over to the next map in the 'spawnspot' global. Maps will be saved+reloaded until the extra argument is omitted again, purging all saved maps. Saved games will contain a copy of each preserved map. parm1-parm64 globals can be used, giving more space to transfer more player data. */ -#define FTE_QC_CHECKCOMMAND /* Provides a way to test if a console command exists, and whether its a command/alias/cvar. Does not say anything about the expected meanings of any arguments or values. */ -#define FTE_QC_CHECKPVS -#define FTE_QC_CROSSPRODUCT -#define FTE_QC_CUSTOMSKINS /* The engine supports the use of q3 skins, as well as the use of such skin 'files' to specify rich top+bottom colours, qw skins, geomsets, or texture composition even on non-players.. */ -#define FTE_QC_DIGEST_SHA1 /* The digest_hex builtin supports 160-bit sha1 hashes. */ -#define FTE_QC_DIGEST_SHA224 /* The digest_hex builtin supports 224-bit sha2 hashes. */ -#define FTE_QC_DIGEST_SHA384 /* The digest_hex builtin supports 384-bit sha2 hashes. */ -#define FTE_QC_DIGEST_SHA512 /* The digest_hex builtin supports 512-bit sha2 hashes. */ -#define FTE_QC_FS_SEARCH_SIZEMTIME -#define FTE_QC_HARDWARECURSORS /* setcursormode exists in both csqc+menuqc, and accepts additional arguments to specify a cursor image to use when this module has focus. If the image exceeds hardware limits (or hardware cursors are unsupported), it will be emulated using regular draws - this at least still avoids conflicting cursors as only one will ever be used, even if console+menu+csqc are all overlayed. */ -#define FTE_QC_HASHTABLES /* Provides efficient string-based lookups. */ -#define FTE_QC_INFOKEY /* QuakeWorld's infokey builtin works, and reports at least name+topcolor+bottomcolor+ping(in ms)+ip(unmasked, but not always ipv4)+team(aka bottomcolor in nq). Does not require actual localinfo/serverinfo/userinfo, but they're _highly_ recommended to any engines with csqc */ -#define FTE_QC_INTCONV /* Provides string<>int conversions, including hex representations. */ -#define FTE_QC_MATCHCLIENTNAME -#define FTE_QC_MULTICAST /* QuakeWorld's multicast builtin works along with MSG_MULTICAST, but also with unicast support. */ -#define FTE_QC_PAUSED -#define FTE_QC_PERSISTENTTEMPSTRINGS /* Supersedes DP_QC_MULTIPLETEMPSTRINGS. Temp strings are garbage collected automatically, and do not expire while they're still in use. This makes strzone redundant. */ -#define FTE_QC_RAGDOLL_WIP -#define FTE_QC_SENDPACKET /* Allows the use of out-of-band udp packets to/from other hosts. Includes the SV_ParseConnectionlessPacket event. */ -#define FTE_QC_STUFFCMDFLAGS /* Variation on regular stuffcmd that gives control over how spectators/mvds should be treated. */ -#define FTE_QC_TRACETRIGGER -#define FTE_QUAKE2_CLIENT /* This engine is able to act as a quake2 client */ -#define FTE_QUAKE2_SERVER /* This engine is able to act as a quake2 server */ -#define FTE_QUAKE3_CLIENT /* This engine is able to act as a quake3 client */ -#define FTE_QUAKE3_SERVER /* This engine is able to act as a quake3 server */ -#define FTE_SOLID_BSPTRIGGER /* Allows for mappers to use shaped triggers instead of being limited to axially aligned triggers. */ -#define FTE_SOLID_LADDER /* Allows a simple trigger to remove effects of gravity (solid 20). obsolete. will prolly be removed at some point as it is not networked properly. Use FTE_ENT_SKIN_CONTENTS */ -#define FTE_SPLITSCREEN /* Client supports splitscreen, controlled via cl_splitscreen. Servers require allow_splitscreen 1 if splitscreen is to be used over the internet. Mods that use csqc will need to be aware for this to work properly. per-client networking may be problematic. */ -#define FTE_SQL /* Provides sql* builtins which can be used for sql database access */ -#define FTE_SQL_SQLITE /* SQL functionality is able to utilise sqlite databases */ -#define FTE_STRINGS /* Extra builtins (and additional behaviour) to make string manipulation easier */ -#define FTE_SV_POINTPARTICLES /* Specifies that particleeffectnum, pointparticles, and trailparticles exist in ssqc as well as csqc. particleeffectnum acts as a precache, allowing ssqc values to be networked up with csqc for use. Use in combination with FTE_PART_SCRIPT+FTE_PART_NAMESPACES to use custom effects. This extension is functionally identical to the DP version, but avoids any misplaced assumptions about the format of the client's particle descriptions. */ -#define FTE_SV_REENTER -#define FTE_TE_STANDARDEFFECTBUILTINS /* Provides builtins to replace writebytes, with a QW compatible twist. */ -#define FTE_TERRAIN_MAP /* This engine supports .hmp files, as well as terrain embedded within bsp files. */ -#define FTE_RAW_MAP /* This engine supports directly loading .map files, as well as realtime editing of the various brushes. */ -#define FTE_INFOBLOBS /* Removes the length limits on user/server/local info strings, and allows embedded nulls and other otherwise-reserved characters. This can be used to network avatar images and the like, or other binary data. */ -#define FTE_VRINPUTS /* input_weapon, input_left_*, input_right_*, input_head_* work, both in csqc (as inputs with suitable plugin/hardware support) and ssqc (available in PlayerPreThink). */ -#define KRIMZON_SV_PARSECLIENTCOMMAND /* SSQC's SV_ParseClientCommand function is able to handle client 'cmd' commands. The tokenizing parts also work in csqc. */ -#define NEH_CMD_PLAY2 -#define NEH_RESTOREGAME -#define QSG_CVARSTRING -#define QW_ENGINE -#define QWE_MVD_RECORD /* You can use the easyrecord command to record MVD demos serverside. */ -#define TEI_MD3_MODEL -#define TEI_SHOWLMP2 -#define TENEBRAE_GFX_DLIGHTS /* Allows ssqc to attach rtlights to entities with various special properties. */ -#define ZQ_MOVETYPE_FLY /* MOVETYPE_FLY works on players. */ -#define ZQ_MOVETYPE_NOCLIP /* MOVETYPE_NOCLIP works on players. */ -#define ZQ_MOVETYPE_NONE /* MOVETYPE_NONE works on players. */ -#define ZQ_VWEP -#define ZQ_QC_STRINGS /* The strings-only subset of FRIK_FILE is supported. */ - -#ifdef _ACCESSORS -accessor strbuf : float; -accessor searchhandle : float; -accessor hashtable : float; -accessor infostring : string; -accessor filestream : float; -accessor filestream : float; -#else -#define strbuf float -#define searchhandle float -#define hashtable float -#define infostring string -#define filestream float -#endif - -entity self; /* The magic me */ -#if defined(CSQC) || defined(SSQC) -entity other; /* Valid in touch functions, this is the entity that we touched. */ -entity world; /* The null entity. Hurrah. Readonly after map spawn time. */ -float time; /* The current game time. Stops when paused. */ -#endif -#ifdef CSQC -float cltime; /* A local timer that ticks relative to local time regardless of latency, packetloss, or pause. */ -#endif -#if defined(CSQC) || defined(SSQC) -float frametime; /* The time since the last physics/render/input frame. */ -#endif -#ifdef CSQC -float player_localentnum; /* This is entity number the player is seeing from/spectating, or the player themself, can change mid-map. */ -float player_localnum; /* The 0-based player index, valid for getplayerkeyvalue calls. */ -float maxclients; /* Maximum number of player slots on the server. */ -float clientcommandframe; /* This is the input-frame sequence. frames < clientcommandframe have been sent to the server. frame==clientcommandframe is still being generated and can still change. */ -float servercommandframe; /* This is the input-frame that was last acknowledged by the server. Input frames greater than this should be applied to the player's entity. */ -#endif -#if defined(QWSSQC) -entity newmis; /* A named entity that should be run soon, to reduce the effects of latency. */ -#endif -#ifdef SSQC -float force_retouch; /* If positive, causes all entities to check for triggers. */ -#endif -#if defined(CSQC) || defined(SSQC) -string mapname; /* The short name of the map. */ -#endif -#if defined(NQSSQC) -float deathmatch; -float coop; -float teamplay; -#endif -#ifdef SSQC -float serverflags; -float total_secrets; -float total_monsters; -float found_secrets; -float killed_monsters; -float parm1; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ -float parm2; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ -float parm3; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ -float parm4; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ -float parm5; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ -float parm6; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ -float parm7; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ -float parm8; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ -float parm9; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ -float parm10; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ -float parm11; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ -float parm12; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ -float parm13; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ -float parm14; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ -float parm15; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ -float parm16; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ -#endif -#ifdef CSQC -float intermission; -#endif -#if defined(CSQC) || defined(SSQC) -vector v_forward; -vector v_up; -vector v_right; -#endif -#ifdef CSQC -vector view_angles; /* +x=DOWN */ -#endif -#if defined(CSQC) || defined(SSQC) -float trace_allsolid; -float trace_startsolid; -float trace_fraction; -vector trace_endpos; -vector trace_plane_normal; -float trace_plane_dist; -entity trace_ent; -float trace_inopen; -float trace_inwater; -#endif -#ifdef CSQC -float input_timelength; -vector input_angles; /* +x=DOWN */ -vector input_movevalues; -float input_buttons; -float input_impulse; -#endif -#ifdef SSQC -entity msg_entity; -void() main; /* This function is never called, and is effectively dead code. */ -void() StartFrame; /* Called at the start of each new physics frame. Player entities may think out of sequence so try not to depend upon explicit ordering too much. */ -void() PlayerPreThink; /* With Prediction(QW compat/FTE default): Called before the player's input commands are processed. -No Prediction(NQ compat): Called AFTER the player's movement intents have already been processed (ie: velocity will have already changed according to input_*, but before the actual position change. */ -void() PlayerPostThink; /* Called after the player's input commands are processed. */ -void() ClientKill; /* Called in response to 'cmd kill' (or just 'kill'). */ -void() ClientConnect; /* Called after the connecting client has finished loading and is ready to receive active entities. Note that this is NOT the first place that a client might be referred to. To determine if the client has csqc active (and kick anyone that doesn't), you can use if(infokeyf(self,INFOKEY_P_CSQCACTIVE)) {sprint(self, "CSQC is required for this server\n");dropclient(self);} */ -void() PutClientInServer; /* Enginewise, this is only ever called immediately after ClientConnect and is thus a little redundant. Modwise, this is also called for respawning a player etc. */ -void() ClientDisconnect; /* Called once a client disconnects or times out. Not guarenteed to be called on map changes. */ -void() SetNewParms; /* Called without context when a new client initially connects (before ClientConnect is even called). This function is expected to only set the parm* globals so that they can be decoded properly later. You should not rely on 'self' being set. */ -void() SetChangeParms; /* Called for each client on map changes. Should copy various entity fields to the parm* globals. */ -#endif -void end_sys_globals; -#if defined(CSQC) || defined(SSQC) -.float modelindex; /* This is the model precache index for the model that was set on the entity, instead of having to look up the model according to the .model field. Use setmodel to change it. */ -.vector absmin; /* Set by the engine when the entity is relinked (by setorigin, setsize, or setmodel). This is in world coordinates. */ -.vector absmax; /* Set by the engine when the entity is relinked (by setorigin, setsize, or setmodel). This is in world coordinates. */ -#endif -#ifdef SSQC -.float ltime; /* On MOVETYPE_PUSH entities, this is used as an alternative to the 'time' global, and .nextthink is synced to this instead of time. This allows time to effectively freeze if the entity is blocked, ensuring the think happens when the entity reaches the target point instead of randomly. */ -#endif -#ifdef CSQC -.float entnum; /* The entity number as its known on the server. */ -.float drawmask; /* Acts as a filter in the addentities call. */ -.float() predraw; /* Called by addentities after the filter and before the entity is actually drawn. Do your interpolation and animation in here. Should return one of the PREDRAW_* constants. */ -#endif -#if defined(QWSSQC) -.float lastruntime; /* This field used to be used to avoid running an entity multiple times in a single frame due to quakeworld's out-of-order thinks. It is no longer used by FTE due to precision issues, but may still be updated for compatibility reasons. */ -#endif -#if defined(CSQC) || defined(SSQC) -.float movetype; /* Describes how the entity moves. One of the MOVETYPE_ constants. */ -.float solid; /* Describes whether the entity is solid or not, and any special properties infered by that. Must be one of the SOLID_ constants */ -.vector origin; /* The current location of the entity in world space. Inline bsp entities (ie: ones placed by a mapper) will typically have a value of '0 0 0' in their neutral pose, as the geometry is offset from that. It is the reference point of the entity rather than the center of its geometry, for non-bsp models, this is often not a significant distinction. */ -.vector oldorigin; /* This is often used on players to reset the player back to where they were last frame if they somehow got stuck inside something due to fpu precision. Never change a player's oldorigin field to inside a solid, because that might cause them to become pemanently stuck. */ -.vector velocity; /* The direction and speed that the entity is moving in world space. */ -.vector angles; /* The eular angles the entity is facing in, in pitch, yaw, roll order. Due to a legacy bug, mdl/iqm/etc formats use +x=UP, bsp/spr/etc formats use +x=DOWN. */ -.vector avelocity; /* The amount the entity's angles change by per second. Note that this is direct eular angles, and thus the angular change is non-linear and often just looks buggy if you're changing more than one angle at a time. */ -#endif -#ifdef CSQC -.float pmove_flags; -#endif -#if defined(NQSSQC) -.vector punchangle; -#endif -#if defined(CSQC) || defined(SSQC) -.string classname; /* Identifies the class/type of the entity. Useful for debugging, also used for loading, but its value is not otherwise significant to the engine, this leaves the mod free to set it to whatever it wants and randomly test strings for values in whatever inefficient way it chooses fit. */ -#endif -#ifdef CSQC -.float renderflags; -#endif -#if defined(CSQC) || defined(SSQC) -.string model; /* The model name that was set via setmodel, in theory. Often, this is cleared to null to prevent the engine from being seen by clients while not changing modelindex. This behaviour allows inline models to remain solid yet be invisible. */ -.float frame; /* The current frame the entity is meant to be displayed in. In CSQC, note the lerpfrac and frame2 fields as well. if it specifies a framegroup, the framegroup will autoanimate in ssqc, but not in csqc. */ -#endif -#ifdef CSQC -.float frame1time; /* The absolute time into the animation/framegroup specified by .frame. */ -.float frame2; /* The alternative frame. Visible only when lerpfrac is set to 1. */ -.float frame2time; /* The absolute time into the animation/framegroup specified by .frame2. */ -.float lerpfrac; /* If 0, use frame1 only. If 1, use frame2 only. Mix them together for values between. */ -#endif -#if defined(CSQC) || defined(SSQC) -.float skin; /* The skin index to use. on a bsp entity, setting this to 1 will switch to the 'activated' texture instead. A negative value will be understood as a replacement contents value, so setting it to CONTENTS_WATER will make a movable pool of water. */ -.float effects; /* Lots of random flags that change random effects. See EF_* constants. */ -.vector mins; /* The minimum extent of the model (ie: the bottom-left coordinate relative to the entity's origin). Change via setsize. May also be changed by setmodel. */ -.vector maxs; /* like mins, but in the other direction. */ -.vector size; /* maxs-mins. Updated when the entity is relinked (by setorigin, setsize, setmodel) */ -.void() touch; -#endif -#ifdef SSQC -.void() use; -#endif -#if defined(CSQC) || defined(SSQC) -.void() think; -.void() blocked; -.float nextthink; /* The time at which the entity is next scheduled to fire its think event. For MOVETYPE_PUSH entities, this is relative to that entity's ltime field, for all other entities it is relative to the time gloal. */ -#endif -#ifdef SSQC -.entity groundentity; -.float health; -.float frags; -.float weapon; -.string weaponmodel; -.float weaponframe; -.float currentammo; -.float ammo_shells; -.float ammo_nails; -.float ammo_rockets; -.float ammo_cells; -.float items; -.float takedamage; -#endif -#if defined(CSQC) || defined(SSQC) -.entity chain; -#endif -#ifdef SSQC -.float deadflag; -.vector view_ofs; -.float button0; -.float button1; -.float button2; -.float impulse; -.float fixangle; /* Forces the clientside view angles to change to the value of .angles (has some lag). If set to 1/TRUE, the server will guess whether to send a delta or an explicit angle. If 2, will always send a delta (due to lag between transmission and acknowledgement, this cannot be spammed reliably). If 3, will always send an explicit angle. */ -.vector v_angle; /* The angles a player is viewing. +x is DOWN (pitch, yaw, roll) */ -#endif -#if defined(NQSSQC) -.float idealpitch; -#endif -#ifdef SSQC -.string netname; -#endif -#if defined(CSQC) || defined(SSQC) -.entity enemy; -.float flags; -.float colormap; -#endif -#ifdef SSQC -.float team; -.float max_health; -.float teleport_time; /* While active, prevents the player from using the +back command, also blocks waterjumping. */ -.float armortype; -.float armorvalue; -.float waterlevel; -.float watertype; -.float ideal_yaw; -.float yaw_speed; -.entity aiment; -.entity goalentity; -.float spawnflags; -.string target; -.string targetname; -.float dmg_take; -.float dmg_save; -.entity dmg_inflictor; -#endif -#if defined(CSQC) || defined(SSQC) -.entity owner; -#endif -#ifdef SSQC -.vector movedir; -.string message; -.float sounds; -.string noise; -.string noise1; -.string noise2; -.string noise3; -#endif -void end_sys_fields; -#ifdef MENU -float time; /* The current local time. Increases while paused. */ -#endif -#if defined(CSQC) || defined(SSQC) -float input_sequence; /* This is the client-generated input sequence number. 0 for unsequenced movements. */ -float input_servertime; /* Server's timestamp of the client's interpolation state. */ -#endif -#ifdef SSQC -float input_timelength; -vector input_angles; /* +x=DOWN */ -vector input_movevalues; -float input_buttons; -float input_impulse; -#endif -#if defined(CSQC) || defined(SSQC) -int trace_endcontents; -int trace_surfaceflags; -int trace_brush_id; -int trace_brush_faceid; -int trace_surface_id; /* 1-based. 0 if not known. */ -int trace_bone_id; /* 1-based. 0 if not known. typically needs MOVE_HITMODEL. */ -int trace_triangle_id; /* 1-based. 0 if not known. */ -#endif -#ifdef CSQC -float trace_networkentity; /* Repots which ssqc entnum was hit when a csqc traceline impacts an ssqc-based brush entity. */ -vector pmove_org; /* Reports the origin of the engineside player (after prediction). Does not work when the player is a csqc-owned entity. */ -vector pmove_vel; /* Reports the velocity of the engineside player (after prediction). Does not work when the player is a csqc-owned entity. */ -float pmove_onground; /* Reports the onground state of the engineside player (after prediction). Does not work when the player is a csqc-owned entity. */ -#endif -#if defined(CSQC) || defined(SSQC) -vector global_gravitydir = '0 0 -1'; /* The direction gravity should act in if not otherwise specified per entity. */ -int serverid; /* The unique id of this server within the server cluster. */ -#endif -#ifdef CSQC -.string message; /* Allows the csqc to read the map description from the server. */ -#endif -#ifdef SSQC -.float button3; -.float button4; -.float button5; -.float button6; -.float button7; -.float button8; -#endif -#if defined(NQSSQC) -.float buttonuse; /* For DP compat only. */ -.float buttonchat; /* For DP compat only. */ -.float cursor_active; /* For DP compat only. */ -.float button9; /* For DP compat only. */ -.float button10; /* For DP compat only. */ -.float button11; /* For DP compat only. */ -.float button12; /* For DP compat only. */ -.float button13; /* For DP compat only. */ -.float button14; /* For DP compat only. */ -.float button15; /* For DP compat only. */ -.float button16; /* For DP compat only. */ -.vector cursor_screen; /* For DP compat only. */ -.vector cursor_start; /* For DP compat only. */ -.vector cursor_impact; /* For DP compat only. */ -.entity cursor_entitynumber; /* For DP compat only. */ -.float lastruntime; /* This field used to be used to avoid running an entity multiple times in a single frame due to quakeworld's out-of-order thinks. It is no longer used by FTE due to precision issues, but may still be updated for compatibility reasons. */ -#endif -#if defined(CSQC) || defined(QWSSQC) -.vector punchangle; -#endif -#if defined(CSQC) || defined(SSQC) -.float gravity; /* Multiplier applied in addition to sv_gravity (not absolute units), to control the gravity affecting this entity specifically. */ -.float hull; /* Overrides the hull used by the entity for walkmove/movetogoal and not traceline/tracebox. */ -.entity movechain; /* This is a linked list of entities which will be moved whenever this entity moves, logically they are attached to this entity. */ -.void() chainmoved; /* Called when the entity is moved as a result of being part of another entity's .movechain */ -.void(float old, float new) contentstransition; /* This function is called when the entity moves between water and air. If specified, default splash sounds will be disabled allowing you to provide your own. */ -.float dimension_solid; /* This is the bitmask of dimensions which the entity is solid within. This is not networked, instead csqc traces impacting ssqc entities assumes the ssqc entity to have a dimension_solid of 1. */ -.float dimension_hit; /* This is the bitmask of dimensions which the entity will be blocked by. If other.dimension_solid & self.dimension_hit, our traces will impact and not proceed. If its false, the traces will NOT impact, allowing self to pass straight through. */ -.int hitcontentsmaski; /* Traces performed for this entity will impact against surfaces that match this contents mask (CONTENTBITS_* constants). */ -__deprecated("Does not support mod-specific contents.") .float dphitcontentsmask; /* Some crappy field that inefficiently requires translating to the native contents flags. Ditch the 'dp', do it properly. */ -.float scale; /* Multiplier that resizes the entity. 1 is normal sized, 2 is double sized. scale 0 is remapped to 1. In SSQC, this is limited to 1/16th precision, with a maximum just shy of 16. */ -.float fatness; /* How many QuakeUnits to push the entity's verticies along their normals by. */ -.float alpha; /* The transparency of the entity. 1 means opaque, 0.0001 means virtually invisible. 0 is remapped to 1, for compatibility. */ -.float modelflags; /* Used to override the flags set in the entity's model. Should be set according to the MF_ constants. Use effects|=EF_NOMODELFLAGS to ignore the model's flags completely. The traileffectnum field is more versatile. */ -#endif -#ifdef SSQC -.float frame1time; /* This controls the time into the framegroup/animation named by .frame, you should increment this value according to frametime or to distance moved, depending on the sort of animation you're attempting. You may wish to avoid incrementing this while lerpfrac is still changing, to avoid wasting parts of the animation. */ -#endif -#if defined(CSQC) || defined(SSQC) -.float basebone; /* The base* frame animations are equivelent to their non-base versions, except that they only affect bone numbers below the 'basebone' value. This means that the base* animation can affect the legs of a skeletal model independantly of the normal animation fields affecting the torso area. For more complex animation than this, use skeletal objects. */ -.float baseframe; /* See basebone */ -.void() customphysics; /* Called once each physics frame, overriding the entity's .movetype field and associated logic. You'll probably want to use tracebox to move it through the world. Be sure to call .think as appropriate. */ -.entity tag_entity; /* Specifies which entity this entity's origin+angles is 'attached' to. */ -.float tag_index; /* Specifies the tag or bone on the parent entity that we're attached to. If this is -1 then the entity is instead a q3-like camera portal, with the tag_entity saying the entity to display for. If tag_entity is world then this is a q3-like portal surface marker with a separate camera (with a tag_entity referring to the portal surface). */ -.float skeletonindex; /* This object serves as a container for the skeletal bone states used to override the animation data. */ -.vector colormod; /* Provides a colour tint for the entity (does not affect fullbrights). */ -.vector glowmod; /* Scaler for an entity's fullbright textures. */ -.vector gravitydir; /* Specifies the direction in which gravity acts. Must be normalised. '0 0 0' also means down. Use '0 0 1' if you want the player to be able to run on ceilings. */ -.vector(vector org, vector ang) camera_transform; /* A callback that provides portal transform information for portal surfaces attached to this entity. Also used to open up pvs in ssqc. */ -#endif -#ifdef SSQC -.float pmove_flags; -#endif -#if defined(CSQC) || defined(SSQC) -.float geomtype; -.float friction; -.float erp; -.float jointtype; -.float mass; -.float bouncefactor; -.float bouncestop; -#endif -#if defined(CSQC) || defined(QWSSQC) -.float idealpitch; -#endif -#if defined(CSQC) || defined(SSQC) -.float pitch_speed; -.float drawflags; /* Various flags that affect lighting values and scaling. Typically set to 96 in quake for proper compatibility with DP_QC_SCALE. */ -.float abslight; /* Allows overriding light levels. Use drawflags to state that this field should actually be used. */ -.vector color; /* This affects the colour of realtime lights that were enabled via the pflags field. */ -.float light_lev; /* This is the radius of an entity's light. This is not normally used by the engine, but is used for realtime lights (ones that are enabled with the pflags field). */ -.float style; /* Used by the light util to decide how an entity's light should animate. On an entity with pflags set, this also affects realtime lights. */ -.float pflags; /* Realtime lighting flags */ -#endif -#ifdef SSQC -.float maxspeed; -.entity view2; /* defines a second viewpoint, typically displayed in a corner of the screen (also punches open pvs). */ -.vector movement; /* These are the directions that the player is currently trying to move in (ie: which +forward/+moveright/+moveup etc buttons they have held), expressed relative to that player's angles. Order is forward, right, up. */ -.float vw_index; /* This acts as a second modelindex, using the same frames etc. */ -__deprecated("Cannot be recorded in MVDs, nor work properly with splitscreen. Use CSQC instead.") .entity nodrawtoclient; /* This entity will not be sent to the player named by this field. They will be invisible and not emit dlights/particles. Does not work in MVD-recorded game. */ -__deprecated("Cannot be recorded in MVDs, nor work properly with splitscreen. Use CSQC instead.") .entity drawonlytoclient; /* This entity will be sent *only* to the player named by this field. To other players they will be invisible and not emit dlights/particles. Does not work in MVD-recorded game. */ -__deprecated("Redundant. Cannot be recorded in MVDs, nor work properly with splitscreen. Use CSQC instead.") .entity viewmodelforclient; /* This entity will be sent only to the player named by this field, and this entity will be attached to the player's view as an additional weapon model. */ -__deprecated("Cannot be recorded in MVDs, nor work properly with splitscreen. Use CSQC instead.") .entity exteriormodeltoclient; /* This entity will be invisible to the player named by this field, except in mirrors or mirror-like surfaces, where it will be visible as normal. It may still cast shadows as normal, and generate lights+particles, depending on client settings. Does not affect how other players see the entity. */ -.entity clientcamera; /* Controls which entity to use for this client's camera. */ -.float glow_size; /* Some outdated particle trail thing. */ -.float glow_color; /* Some outdated particle trail thing. */ -.float glow_trail; /* Some outdated particle trail thing. */ -.float traileffectnum; /* This should be set to the result of particleeffectnum, in order to attach a custom trail effect to an entity as it moves. */ -.float emiteffectnum; /* This should be set to the result of particleeffectnum, in order to continually spawn particles in the direction that this entity faces. */ -__deprecated("Does not work with MVDs nor splitscreen.") .float dimension_see; /* This is the dimension mask (bitfield) that the client is allowed to see. Entities and events not in this dimension mask will be invisible. */ -__deprecated("Does not work with MVDs nor splitscreen.") .float dimension_seen; /* This is the dimension mask (bitfield) that the client is visible within. Clients that cannot see this dimension mask will not see this entity. */ -__deprecated("Does not work with MVDs nor splitscreen.") .float dimension_ghost; /* If this entity is visible only within these dimensions, it will become transparent, as if a ghost. */ -__deprecated("Does not work with MVDs nor splitscreen.") .float dimension_ghost_alpha; /* If this entity is subject to dimension_ghost, this is the scaler for its alpha value. If 0, 0.5 will be used instead. */ -.float(entity playerent, float changedflags) SendEntity; /* Called by the engine whenever an entity needs to be (re)sent to a client's csprogs, either because SendFlags was set or because data was lost. Must write its data to the MSG_ENTITY buffer. Will be called at the engine's leasure. */ -.float SendFlags; /* Indicates that something in the entity has been changed, and that it needs to be updated to all players that can see it. The engine will clear it at some point, with the cleared bits appearing in the 'changedflags' argument of the SendEntity method. */ -__deprecated("Use SendFlags instead.") .float Version; /* Obsolete */ -__deprecated("Doesn't support RGB player colours.") .float clientcolors; -.float viewzoom; -.float playerclass; -.float hasted; -.float light_level; /* Used by hexen2 to indicate the light level where the player is standing. */ -.float pvsflags; /* Reconfigures when the entity is visible to clients */ -.float uniquespawnid; /* Incremented by 1 whenever the entity is respawned. Persists across remove calls, for when the two-second grace period is insufficient. */ -DEP_CSQC .float() customizeentityforclient; /* Called just before an entity is sent to a client (non-csqc protocol). This gives you a chance to tailor 'self' according to what 'other' should see. */ -#endif -#ifdef CSQC -.float frame3; /* Some people just don't understand how to use framegroups... */ -.float frame3time; /* .frame3 equivelent of frame1time. */ -.float lerpfrac3; /* Weight of .frame3 - .frame's weight is automatically calculated as 1-(lerpfrac+lerpfrac3+lerpfrac4), as a result these fields should NEVER add to above 1. */ -.float frame4; -.float frame4time; /* .frame4 equivelent of frame1time. */ -.float lerpfrac4; -.float forceshader; /* Contains a shader handle used to replace all surfaces upon the entity. */ -.float baseframe2; /* See basebone */ -.float baseframe1time; /* See basebone */ -.float baseframe2time; /* See basebone */ -.float baselerpfrac; /* See basebone */ -.float bonecontrol1; /* Halflife model format bone controller. On player models, this typically affects the spine's yaw. */ -.float bonecontrol2; /* Halflife model format bone controller. On player models, this typically affects the spine's yaw. */ -.float bonecontrol3; /* Halflife model format bone controller. On player models, this typically affects the spine's yaw. */ -.float bonecontrol4; /* Halflife model format bone controller. On player models, this typically affects the spine's yaw. */ -.float bonecontrol5; /* Halflife model format bone controller. This typically affects the mouth. */ -.float subblendfrac; /* Weird animation value specific to halflife models. On player models, this typically affects the spine's pitch, or yaw, or... */ -.float subblend2frac; /* Weird animation value specific to halflife models. I've no idea what this does, probably nothing for most models. */ -.float basesubblendfrac; /* See basebone */ -.float basesubblend2frac; /* See basebone */ -#endif -void(float reqid, float responsecode, string resourcebody, int resourcebytes) URI_Get_Callback; /* Called as an eventual result of the uri_get builtin. */ -#ifdef SSQC -void() SpectatorConnect; /* Called when a spectator joins the game. */ -void() SpectatorDisconnect; /* Called when a spectator disconnects from the game. */ -void() SpectatorThink; /* Called each frame for each spectator. */ -void(string cmd) SV_ParseClientCommand; /* Provides QC with a way to intercept 'cmd foo' commands from the client. Very handy. Self will be set to the sending client, while the 'cmd' argument can be tokenize()d and each element retrieved via argv(argno). Unrecognised cmds MUST be passed on to the clientcommand builtin. */ -void(string dest, string from, string cmd, string info) SV_ParseClusterEvent; /* Part of cluster mode. Handles cross-node events that were sent via clusterevent, on behalf of the named client. */ -float(string sender, string body) SV_ParseConnectionlessPacket; /* Provides QC with a way to communicate between servers, or with client server browsers. Sender is the sender's ip. Body is the body of the message. You'll need to add your own password/etc support as required. Self is not valid. */ -void(float pauseduration) SV_PausedTic; /* For each frame that the server is paused, this function will be called to give the gamecode a chance to unpause the server again. the pauseduration argument says how long the server has been paused for (the time global is frozen and will not increment while paused). Self is not valid. */ -float(float newstatus) SV_ShouldPause; /* Called to give the qc a change to block pause/unpause requests. Return false for the pause request to be ignored. newstatus is 1 if the user is trying to pause the game. For the duration of the call, self will be set to the player who tried to pause, or to world if it was triggered by a server-side event. */ -void() SV_RunClientCommand; /* Called each time a player movement packet was received from a client. Self is set to the player entity which should be updated, while the input_* globals specify the various properties stored within the input packet. The contents of this function should be somewaht identical to the equivelent function in CSQC, or prediction misses will occur. If you're feeling lazy, you can simply call 'runstandardplayerphysics' after modifying the inputs. */ -void() SV_AddDebugPolygons; /* Called each video frame. This is the only place where ssqc is allowed to call the R_BeginPolygon/R_PolygonVertex/R_EndPolygon builtins. This is exclusively for debugging, and will break in anything but single player as it will not be called if the engine is not running both a client and a server. */ -DEP_CSQC void() SV_PlayerPhysics; /* Compatibility method to tweak player input that does not reliably work with prediction (prediction WILL break). Mods that care about prediction should use SV_RunClientCommand instead. If pr_no_playerphysics is set to 1, this function will never be called, which will either fix prediction or completely break player movement depending on whether the feature was even useful. */ -void(float fd, float entcount, float playerslots) SV_PerformSave; /* Called by the engine as part of saved games. The QC is responsible for writing any data that will be required to restore the game. Save files are not limited to just text, you can use fwrite (and later fread) for binary data. Remember to close the passed file. */ -void(float fd, float entcount, float playerslots) SV_PerformLoad; /* Called by the engine to restore a saved game that was saved via SV_PerformSave, the server will have already started the game to its inital state (for precaches+makestatic calls), so entities+globals will have their post-spawn values (you will likely want to remove most of them, you can use the two extra args as helpers for that). You can use respawn_edict to un-remove specific entities, with parseentitydata or putentityfieldstring(findentityfield(NAME), ent, value) to assign to fields by name strings. Don't expect bprints/etc to work - players are likely in a pending state. Remember to close the passed file. */ -void() RestoreGame; /* Called for each reconnecting player as part of loading a saved game. Part of NEH_RESTOREGAME. */ -void() EndFrame; /* Called after non-player entities have been run at the end of the physics frame. Player physics is performed out of order and can/will still occur between EndFrame and BeginFrame. */ -void() SetTransferParms; /* Called as an alternative to SetChangeParms when a player is transferring to another server. Part of FTE_SV_CLUSTER. */ -string(string addr, string uinfo, string features) SV_CheckRejectConnection; /* Called to give the mod a chance to ignore connection requests based upon client protocol support or other properties. Use infoget to read the uinfo and features arguments. */ -#endif -#ifdef CSQC -void(float apilevel, string enginename, float engineversion) CSQC_Init; /* Called at startup. enginename and engineversion are arbitary hints and can take any form. enginename should be consistant between revisions, but this cannot truely be relied upon. */ -void() CSQC_WorldLoaded; /* Called after the server's model+sound precaches have been executed. Gives a chance for the qc to read the entity lump from the bsp (via getentitytoken). */ -void() CSQC_Shutdown; /* Specifies that the csqc is going down. Save your persistant settings here. */ -void(float vwidth, float vheight, float notmenu) CSQC_UpdateView; /* Called every single video frame. The CSQC is responsible for rendering the entire screen. */ -void(float vwidth, float vheight, float notmenu) CSQC_UpdateViewLoading; /* Alternative to CSQC_UpdateView, called when the engine thinks there should be a loading screen. If present, will inhibit the engine's normal loading screen, deferring to qc to draw it. */ -void(vector viewsize, float scoresshown) CSQC_DrawHud; /* Part of simple csqc, called after drawing the 3d view whenever CSQC_UpdateView is not defined. */ -void(vector viewsize, float scoresshown) CSQC_DrawScores; /* Part of simple csqc, called after CSQC_DrawHud whenever CSQC_UpdateView is not defined, and when there are no menus/console active. */ -void(string msg) CSQC_Parse_StuffCmd; /* Gives the CSQC a chance to intercept stuffcmds. Use the tokenize builtin to parse the message. Unrecognised commands would normally be localcmded, but its probably better to drop unrecognised stuffcmds completely. */ -float(string msg) CSQC_Parse_CenterPrint; /* Gives the CSQC a chance to intercept centerprints. Return true if you wish the engine to otherwise ignore the centerprint. */ -float(float save, float take, vector inflictororg) CSQC_Parse_Damage; /* Called as a result of player.dmg_save or player.dmg_take being set on the server. -Return true to completely inhibit the engine's colour shift and damage rolls, allowing you to do your own thing. -You can use punch_roll += (normalize(inflictororg-player.origin)*v_right)*(take+save)*autocvar_v_kickroll; as a modifier for the roll angle should the player be hit from the side, and slowly fade it away over time. */ -void(string printmsg, float printlvl) CSQC_Parse_Print; /* Gives the CSQC a chance to intercept sprint/bprint builtin calls. CSQC should filter by the client's current msg setting and then pass the message on to the print command, or handle them itself. */ -void() CSQC_Parse_Event; /* Called when the client receives an SVC_CGAMEPACKET. The csqc should read the data or call the error builtin if it does not recognise the message. */ -float(float evtype, float scanx, float chary, float devid) CSQC_InputEvent; /* Called whenever a key is pressed, the mouse is moved, etc. evtype will be one of the IE_* constants. The other arguments vary depending on the evtype. Key presses are not guarenteed to have both scan and unichar values set at the same time. */ -__used void() CSQC_Input_Frame; /* Called just before each time clientcommandframe is updated. You can edit the input_* globals in order to apply your own player inputs within csqc, which may allow you a convienient way to pass certain info to ssqc. */ -void(string rendererdescription) CSQC_RendererRestarted; /* Called by the engine after the video was restarted. This serves to notify the CSQC that any render targets that it may have cached were purged, and will need to be regenerated. */ -float(string cmd) CSQC_ConsoleCommand; /* Called if the user uses any console command registed via registercommand. */ -float(string text, string info) CSQC_ConsoleLink; /* Called if the user clicks a ^[text\infokey\infovalue^] link. Use infoget to read/check each supported key. Return true if you wish the engine to not attempt to handle the link itself. -WARNING: link text can potentially come from other players, so be careful about what you allow to be changed. */ -void(float entnum) CSQC_Ent_Spawn; /* Clumsily defined function for compat with DP. Should call spawn, set that ent's entnum field, and return the entity inside the 'self' global which will then be used for fllowing Ent_Updates. MUST NOT PARSE ANY NETWORK DATA (which makes it kinda useless). */ -void(float isnew) CSQC_Ent_Update; /* Parses the data sent by ssqc's various SendEntity functions (must use the exact same reads as the ssqc used writes - to debug this rule more easily, you may wish to use sv_csqcdebug). 'self' provides context between frames, and self.entnum should normally report which ssqc entity . Be aware that interpolation will need to happen separately. */ -void() CSQC_Ent_Remove; -float(float entnum, float channel, string soundname, float vol, float attenuation, vector pos, float pitchmod, float flags) CSQC_Event_Sound; -float() CSQC_Parse_TempEntity; /* Please don't use this. Use CSQC_Parse_Event and multicasts instead. -The use of serverside protocol translation to handle QW vs NQ protocols mean that you're likely to end up reading slightly different data. Which is bad. -Return true to say that you fully handled the tempentity. Return false to have the client attempt to rewind the network stream and parse the message itself. */ -#endif -#if defined(CSQC) || defined(MENU) -void(string cmdtext) GameCommand; -#endif -string(string uri, string method, string postdata, __in string requestheaders, __inout string responseheaders) Cef_GeneratePage; /* Provides an entrypoint to generate pages for the CEF plugin from within QC. Headers are --separated key/value pairs (use tokenizebyseparator). */ -#ifdef SSQC +/* +This file was generated by FTE Quake 6278M, dated Jun 27 2022. +This file can be regenerated by issuing the following command: +pr_dumpplatform +(Use the -help arg for a list of available args) +*/ +#pragma noref 1 +//#pragma flag enable logicops +#pragma warning error Q101 /*too many parms. The vanilla qcc didn't validate properly, hence why fteqcc normally treats it as a warning.*/ +#pragma warning error Q105 /*too few parms. The vanilla qcc didn't validate properly, hence why fteqcc normally treats it as a warning.*/ +#pragma warning error Q106 /*assignment to constant/lvalue. Define them as var if you want to initialise something.*/ +#pragma warning error Q208 /*system crc unknown. Compatibility goes out of the window if you disable this.*/ +#pragma warning enable F301 /*non-utf-8 strings. Think of the foreigners! Also think of text editors that insist on screwing up your char encodings.*/ +#pragma warning enable F302 /*uninitialised locals. They usually default to 0 in qc (except in recursive functions), but its still probably a bug*/ +#if !defined(CSQC) && !defined(NQSSQC) && !defined(QWSSQC)&& !defined(MENU) + #ifdef QUAKEWORLD + #define QWSSQC + #else + #define NQSSQC + #endif +#endif +#if !defined(SSQC) && (defined(QWSSQC) || defined(NQSSQC)) + #define SSQC +#endif +#if defined(CSQC) || defined(MENU) + #define DEP_CSQC DEP +#else + #define DEP_CSQC __deprecated("Use CSQC for this") +#endif +#ifndef DEP + #define DEP __deprecated //predefine this if you want to avoid our deprecation warnings. +#endif +#ifndef FTEDEP + #define FTEDEP(reason) //for symbols deprecated in FTE that may still be useful/required for other engines +#endif +#define BX_COLOREDTEXT +#define DP_CON_SET /* The 'set' console command exists, and can be used to create/set cvars. */ +#define DP_CON_SETA /* The 'seta' console command exists, like the 'set' command, but also marks the cvar for archiving, allowing it to be written into the user's config. Use this command in your default.cfg file. */ +#define DP_CSQC_ROTATEMOVES +#define DP_EF_ADDITIVE +#define DP_ENT_ALPHA +#define DP_EF_BLUE +#define DP_EF_FULLBRIGHT +#define DP_EF_NODEPTHTEST +#define DP_EF_NODRAW +#define DP_EF_NOGUNBOB +#define DP_EF_NOSHADOW +#define DP_EF_RED +#define DP_ENT_COLORMOD +#define DP_ENT_CUSTOMCOLORMAP +#define DP_ENT_EXTERIORMODELTOCLIENT +#define DP_ENT_SCALE +#define DP_ENT_TRAILEFFECTNUM /* self.traileffectnum=particleeffectnum("myeffectname"); can be used to attach a particle trail to the given server entity. This is equivelent to calling trailparticles each frame. */ +#define DP_ENT_VIEWMODEL +#define DP_GECKO_SUPPORT +#define DP_GFX_FONTS +#define DP_GFX_QUAKE3MODELTAGS +#define DP_GFX_SKINFILES +#define DP_GFX_SKYBOX +#define DP_HALFLIFE_MAP +#define DP_HALFLIFE_MAP_CVAR +#define DP_INPUTBUTTONS +#define DP_LIGHTSTYLE_STATICVALUE +#define DP_LITSUPPORT +#define DP_MONSTERWALK /* MOVETYPE_WALK is valid on non-player entities. Note that only players receive acceleration etc in line with none/bounce/fly/noclip movetypes on the player, thus you will have to provide your own accelerations (incluing gravity) yourself. */ +#define DP_MOVETYPEBOUNCEMISSILE +#define DP_MOVETYPEFOLLOW +#define DP_QC_ASINACOSATANATAN2TAN +#define DP_QC_CHANGEPITCH +#define DP_QC_COPYENTITY +#define DP_QC_CRC16 +#define DP_QC_CVAR_DEFSTRING +#define DP_QC_CVAR_STRING +#define DP_QC_CVAR_TYPE +#define DP_QC_DIGEST_SHA256 +#define DP_QC_EDICT_NUM +#define DP_QC_ENTITYDATA +#define DP_QC_ETOS +#define DP_QC_FINDCHAIN +#define DP_QC_FINDCHAINFLOAT +#define DP_QC_FINDFLAGS +#define DP_QC_FINDCHAINFLAGS +#define DP_QC_FINDFLOAT +#define DP_QC_FS_SEARCH +#define DP_QC_FS_SEARCH_PACKFILE +#define DP_QC_GETLIGHT +#define DP_QC_GETSURFACE +#define DP_QC_GETSURFACEPOINTATTRIBUTE +#define DP_QC_GETTAGINFO +#define DP_QC_I18N /* Specifies that the engine uses $MODULE.dat.$LANG.po files that translates the dotranslate_* globals on load - these are usually created via the _("foo") qcc intrinsic. */ +#define DP_QC_MINMAXBOUND +#define DP_QC_MULTIPLETEMPSTRINGS /* Superseded by DP_QC_UNLIMITEDTEMPSTRINGS. Functions that return a temporary string will not overwrite/destroy previous temporary strings until at least 16 strings are returned (or control returns to the engine). */ +#define DP_QC_RANDOMVEC +#define DP_QC_RENDER_SCENE /* clearscene+addentity+setviewprop+renderscene+setmodel are available to menuqc. WARNING: DP advertises this extension without actually supporting it, FTE does actually support it. */ +#define DP_QC_SINCOSSQRTPOW +#define DP_QC_SPRINTF /* Provides the sprintf builtin, which allows for rich formatting along the lines of C's function with the same name. Not to be confused with QC's sprint builtin. */ +#define DP_QC_STRFTIME +#define DP_QC_STRING_CASE_FUNCTIONS +#define DP_QC_STRINGBUFFERS +#define DP_QC_STRINGCOLORFUNCTIONS +#define DP_QC_STRREPLACE +#define DP_QC_TOKENIZEBYSEPARATOR +#define DP_QC_TRACEBOX +#define DP_QC_TRACETOSS +#define DP_QC_TRACE_MOVETYPE_HITMODEL +#define DP_QC_TRACE_MOVETYPE_WORLDONLY +#define DP_QC_TRACE_MOVETYPES +#define DP_QC_UNLIMITEDTEMPSTRINGS /* Supersedes DP_QC_MULTIPLETEMPSTRINGS, superseded by FTE_QC_PERSISTENTTEMPSTRINGS. Specifies that all temp strings will be valid at least until the QCVM returns. */ +#define DP_QC_URI_ESCAPE +#define DP_QC_URI_GET +#define DP_QC_URI_POST +#define DP_QC_VECTOANGLES_WITH_ROLL +#define DP_QC_VECTORVECTORS +#define DP_QC_WHICHPACK +#define DP_QUAKE2_MODEL +#define DP_QUAKE2_SPRITE +#define DP_QUAKE3_MAP +#define DP_QUAKE3_MODEL +#define DP_REGISTERCVAR +#define DP_SND_SOUND7_WIP2 +#define DP_SND_STEREOWAV +#define DP_SND_OGGVORBIS +#define DP_SOLIDCORPSE +#define DP_SPRITE32 +#define DP_SV_BOTCLIENT +#define DP_SV_CLIENTCAMERA /* Works like svc_setview except also handles pvs. */ +#define DP_SV_CLIENTCOLORS /* Provided only for compatibility with DP. */ +#define DP_SV_CLIENTNAME /* Provided only for compatibility with DP. */ +#define DP_SV_CUSTOMIZEENTITYFORCLIENT /* Deprecated feature for compat with DP. Can be slow, incompatible with splitscreen, usually malfunctions with mvds. */ +#define DP_SV_DRAWONLYTOCLIENT +#define DP_SV_DROPCLIENT /* Equivelent to quakeworld's stuffcmd(self,"disconnect\n"); hack */ +#define DP_SV_EFFECT +#define DP_SV_EXTERIORMODELFORCLIENT +#define DP_SV_NODRAWTOCLIENT +#define DP_SV_PLAYERPHYSICS /* Allows reworking parts of NQ player physics. USE AT OWN RISK - this necessitates NQ physics and is thus guarenteed to break prediction. */ +#define DP_SV_POINTSOUND +#define DP_SV_PRECACHEANYTIME /* Specifies that the various precache builtins can be called at any time. WARNING: precaches are sent reliably while sound events, modelindexes, and particle events are not. This can mean sounds and particles might not work the first time around, or models may take a while to appear (after the reliables are received and the model is loaded from disk). Always attempt to precache a little in advance in order to reduce these issues (preferably at the start of the map...) */ +#define DP_SV_PRINT /* Says that the print builtin can be used from nqssqc (as well as just csqc), bypassing the developer cvar issues. */ +#define DP_SV_ROTATINGBMODEL /* Engines that support this support avelocity on MOVETYPE_PUSH entities, pushing entities out of the way as needed. */ +#define DP_SV_SETCOLOR +#define DP_SV_SHUTDOWN +#define DP_SV_SPAWNFUNC_PREFIX +#define DP_SV_WRITEPICTURE +#define DP_SV_WRITEUNTERMINATEDSTRING +#define DP_TE_BLOOD +#define DP_TE_CUSTOMFLASH +#define DP_TE_EXPLOSIONRGB +#define DP_TE_PARTICLECUBE +#define DP_TE_PARTICLERAIN +#define DP_TE_PARTICLESNOW +#define DP_TE_SMALLFLASH +#define DP_TE_SPARK +#define DP_TE_STANDARDEFFECTBUILTINS +#define DP_VIEWZOOM +#define EXT_BITSHIFT +#define EXT_CSQC +#define EXT_CSQC_SHARED +#define EXT_DIMENSION_VISIBILITY +#define EXT_DIMENSION_PHYSICS +#define EXT_DIMENSION_GHOST +#define FRIK_FILE +#define FTE_CALLTIMEOFDAY /* Replication of mvdsv functionality (call calltimeofday to cause 'timeofday' to be called, with arguments that can be saved off to a global). Generally strftime is simpler to use. */ +#define FTE_CSQC_ALTCONSOLES /* The engine tracks multiple consoles. These may or may not be directly visible to the user. */ +#define FTE_CSQC_BASEFRAME /* Specifies that .basebone, .baseframe2, .baselerpfrac, baseframe1time, etc exist in csqc. These fields affect all bones in the entity's model with a lower index than the .basebone field, allowing you to give separate control to the legs of a skeletal model, without affecting the torso animations. */ +#define FTE_CSQC_HALFLIFE_MODELS +#define FTE_CSQC_SERVERBROWSER /* Provides builtins to query the engine's serverbrowser servers list from ssqc. Note that these builtins are always available in menuqc. */ +#define FTE_CSQC_SKELETONOBJECTS /* Provides container objects for skeletal bone data, which can be modified on a per bone basis if needed. This allows you to dynamically generate animations (or just blend them with greater customisation) instead of being limited to a single animation or two. */ +#define FTE_CSQC_RAWIMAGES /* Provides raw rgba image access to csqc. With this, the csprogs can read textures into qc-accessible memory, modify it, and then upload it to the renderer. */ +#define FTE_CSQC_RENDERTARGETS /* VF_RT_DESTCOLOUR exists and can be used to redirect any rendering to a texture instead of the screen. */ +#define FTE_CSQC_REVERB /* Specifies that the mod can create custom reverb effects. Whether they will actually be used or not depends upon the sound driver. */ +#define FTE_CSQC_WINDOWCAPTION /* Provides csqc with the ability to change the window caption as displayed when running windowed or in the task bar when switched out. */ +#define FTE_ENT_SKIN_CONTENTS /* self.skin = CONTENTS_WATER; makes a brush entity into water. use -16 for a ladder. */ +#define FTE_ENT_UNIQUESPAWNID +#define FTE_EXTENDEDTEXTCODES +#define FTE_FORCESHADER /* Allows csqc to override shaders on models with an explicitly named replacement. Also allows you to define shaders with a fallback if it does not exist on disk. */ +#define FTE_FORCEINFOKEY /* Provides an easy way to change a user's userinfo from the server. */ +#define FTE_GFX_QUAKE3SHADERS /* specifies that the engine has full support for vanilla quake3 shaders */ +#define FTE_GFX_REMAPSHADER /* With the raw power of stuffcmds, the r_remapshader console command is exposed! This mystical command can be used to remap any shader to another. Remapped shaders that specify $diffuse etc in some form will inherit the textures implied by the surface. */ +#define FTE_GFX_IQM_HITMESH /* Supports hitmesh iqm extensions. Also supports geomsets and embedded events. */ +#define FTE_GFX_MODELEVENTS /* Provides a query for per-animation events in model files, including from progs/foo.mdl.events files. */ +#define FTE_ISBACKBUFFERED /* Allows you to check if a client has too many reliable messages pending. */ +#define FTE_MEMALLOC /* Allows dynamically allocating memory. Use pointers to access this memory. Memory will not be saved into saved games. */ +#define FTE_MEDIA_CIN /* playfilm command supports q2 cin files. */ +#define FTE_MEDIA_ROQ /* playfilm command supports q3 roq files. */ +#define FTE_MULTIPROGS /* Multiple progs.dat files can be loaded inside the same qcvm. Insert new ones with addprogs inside the 'init' function, and use externvalue+externset to rewrite globals (and hook functions) to link them together. Note that the result is generally not very clean unless you carefully design for it beforehand. */ +#define FTE_MULTITHREADED /* Faux multithreading, allowing multiple contexts to run in sequence. */ +#define FTE_MVD_PLAYERSTATS /* In csqc, getplayerstat can be used to query any player's stats when playing back MVDs. isdemo will return 2 in this case. */ +#define FTE_PART_SCRIPT /* Specifies that the r_particledesc cvar can be used to select a list of particle effects to load from particles/foo.cfg, the format of which is documented elsewhere. */ +#define FTE_PART_NAMESPACES /* Specifies that the engine can use foo.bar to load effect foo from particle description bar. When used via ssqc, this should cause the client to download whatever effects as needed. */ +#define FTE_PART_NAMESPACE_EFFECTINFO /* Specifies that effectinfo.bar can load effects from effectinfo.txt for DP compatibility. */ +#define FTE_PEXT_SETVIEW /* NQ's svc_setview works correctly even in quakeworld */ +#define FTE_PEXT_LIGHTSTYLECOL +#define FTE_PEXT_VIEW2 +#define FTE_PEXT_FATNESS +#define FTE_PEXT_TE_BULLET +#define FTE_PEXT_FLOATCOORDS +#define FTE_PEXT_Q2BSP /* Specifies that the client supports q2bsps. */ +#define FTE_PEXT_Q3BSP /* Specifies that the client supports q3bsps. */ +#define FTE_HEXEN2 +#define FTE_PEXT_SPAWNSTATIC +#define FTE_PEXT_CUSTOMTENTS +#define FTE_PEXT_256PACKETENTITIES /* Specifies that the client is not limited to vanilla's limit of only 64 ents visible at once. */ +#define FTE_QC_BASEFRAME /* Specifies that .basebone and .baseframe exist in ssqc. These fields affect all bones in the entity's model with a lower index than the .basebone field, allowing you to give separate control to the legs of a skeletal model, without affecting the torso animations, from ssqc. */ +#define FTE_QC_FILE_BINARY /* Extends FRIK_FILE with binary read+write, as well as allowing seeking. Requires pointers. */ +#define FTE_QC_CHANGELEVEL_HUB /* Adds an extra argument to changelevel which is carried over to the next map in the 'spawnspot' global. Maps will be saved+reloaded until the extra argument is omitted again, purging all saved maps. Saved games will contain a copy of each preserved map. parm1-parm64 globals can be used, giving more space to transfer more player data. */ +#define FTE_QC_CHECKCOMMAND /* Provides a way to test if a console command exists, and whether its a command/alias/cvar. Does not say anything about the expected meanings of any arguments or values. */ +#define FTE_QC_CHECKPVS +#define FTE_QC_CROSSPRODUCT +#define FTE_QC_CUSTOMSKINS /* The engine supports the use of q3 skins, as well as the use of such skin 'files' to specify rich top+bottom colours, qw skins, geomsets, or texture composition even on non-players.. */ +#define FTE_QC_DIGEST_SHA1 /* The digest_hex builtin supports 160-bit sha1 hashes. */ +#define FTE_QC_DIGEST_SHA224 /* The digest_hex builtin supports 224-bit sha2 hashes. */ +#define FTE_QC_DIGEST_SHA384 /* The digest_hex builtin supports 384-bit sha2 hashes. */ +#define FTE_QC_DIGEST_SHA512 /* The digest_hex builtin supports 512-bit sha2 hashes. */ +#define FTE_QC_FS_SEARCH_SIZEMTIME +#define FTE_QC_HARDWARECURSORS /* setcursormode exists in both csqc+menuqc, and accepts additional arguments to specify a cursor image to use when this module has focus. If the image exceeds hardware limits (or hardware cursors are unsupported), it will be emulated using regular draws - this at least still avoids conflicting cursors as only one will ever be used, even if console+menu+csqc are all overlayed. */ +#define FTE_QC_HASHTABLES /* Provides efficient string-based lookups. */ +#define FTE_QC_INFOKEY /* QuakeWorld's infokey builtin works, and reports at least name+topcolor+bottomcolor+ping(in ms)+ip(unmasked, but not always ipv4)+team(aka bottomcolor in nq). Does not require actual localinfo/serverinfo/userinfo, but they're _highly_ recommended to any engines with csqc */ +#define FTE_QC_INTCONV /* Provides string<>int conversions, including hex representations. */ +#define FTE_QC_MATCHCLIENTNAME +#define FTE_QC_MULTICAST /* QuakeWorld's multicast builtin works along with MSG_MULTICAST, but also with unicast support. */ +#define FTE_QC_PAUSED +#define FTE_QC_PERSISTENTTEMPSTRINGS /* Supersedes DP_QC_MULTIPLETEMPSTRINGS. Temp strings are garbage collected automatically, and do not expire while they're still in use. This makes strzone redundant. */ +#define FTE_QC_RAGDOLL_WIP +#define FTE_QC_SENDPACKET /* Allows the use of out-of-band udp packets to/from other hosts. Includes the SV_ParseConnectionlessPacket event. */ +#define FTE_QC_STUFFCMDFLAGS /* Variation on regular stuffcmd that gives control over how spectators/mvds should be treated. */ +#define FTE_QC_TRACETRIGGER +#define FTE_QUAKE2_CLIENT /* This engine is able to act as a quake2 client */ +#define FTE_QUAKE2_SERVER /* This engine is able to act as a quake2 server */ +#define FTE_QUAKE3_CLIENT /* This engine is able to act as a quake3 client */ +#define FTE_QUAKE3_SERVER /* This engine is able to act as a quake3 server */ +#define FTE_SOLID_BSPTRIGGER /* Allows for mappers to use shaped triggers instead of being limited to axially aligned triggers. */ +#define FTE_SOLID_LADDER /* Allows a simple trigger to remove effects of gravity (solid 20). obsolete. will prolly be removed at some point as it is not networked properly. Use FTE_ENT_SKIN_CONTENTS */ +#define FTE_SPLITSCREEN /* Client supports splitscreen, controlled via cl_splitscreen. Servers require allow_splitscreen 1 if splitscreen is to be used over the internet. Mods that use csqc will need to be aware for this to work properly. per-client networking may be problematic. */ +#define FTE_SQL /* Provides sql* builtins which can be used for sql database access */ +#define FTE_SQL_SQLITE /* SQL functionality is able to utilise sqlite databases */ +#define FTE_STRINGS /* Extra builtins (and additional behaviour) to make string manipulation easier */ +#define FTE_SV_POINTPARTICLES /* Specifies that particleeffectnum, pointparticles, and trailparticles exist in ssqc as well as csqc. particleeffectnum acts as a precache, allowing ssqc values to be networked up with csqc for use. Use in combination with FTE_PART_SCRIPT+FTE_PART_NAMESPACES to use custom effects. This extension is functionally identical to the DP version, but avoids any misplaced assumptions about the format of the client's particle descriptions. */ +#define FTE_SV_REENTER +#define FTE_TE_STANDARDEFFECTBUILTINS /* Provides builtins to replace writebytes, with a QW compatible twist. */ +#define FTE_TERRAIN_MAP /* This engine supports .hmp files, as well as terrain embedded within bsp files. */ +#define FTE_RAW_MAP /* This engine supports directly loading .map files, as well as realtime editing of the various brushes. */ +#define FTE_INFOBLOBS /* Removes the length limits on user/server/local info strings, and allows embedded nulls and other otherwise-reserved characters. This can be used to network avatar images and the like, or other binary data. */ +#define FTE_VRINPUTS /* input_weapon, input_left_*, input_right_*, input_head_* work, both in csqc (as inputs with suitable plugin/hardware support) and ssqc (available in PlayerPreThink). */ +#define KRIMZON_SV_PARSECLIENTCOMMAND /* SSQC's SV_ParseClientCommand function is able to handle client 'cmd' commands. The tokenizing parts also work in csqc. */ +#define NEH_CMD_PLAY2 +#define NEH_RESTOREGAME +#define QSG_CVARSTRING +#define QW_ENGINE +#define QWE_MVD_RECORD /* You can use the easyrecord command to record MVD demos serverside. */ +#define TEI_MD3_MODEL +#define TEI_SHOWLMP2 +#define TENEBRAE_GFX_DLIGHTS /* Allows ssqc to attach rtlights to entities with various special properties. */ +#define ZQ_MOVETYPE_FLY /* MOVETYPE_FLY works on players. */ +#define ZQ_MOVETYPE_NOCLIP /* MOVETYPE_NOCLIP works on players. */ +#define ZQ_MOVETYPE_NONE /* MOVETYPE_NONE works on players. */ +#define ZQ_VWEP +#define ZQ_QC_STRINGS /* The strings-only subset of FRIK_FILE is supported. */ + +#ifdef _ACCESSORS +accessor strbuf : float; +accessor searchhandle : float; +accessor hashtable : float; +accessor infostring : string; +accessor filestream : float; +accessor filestream : float; +#else +#define strbuf float +#define searchhandle float +#define hashtable float +#define infostring string +#define filestream float +#endif + +entity self; /* The magic me */ +#if defined(CSQC) || defined(SSQC) +entity other; /* Valid in touch functions, this is the entity that we touched. */ +entity world; /* The null entity. Hurrah. Readonly after map spawn time. */ +float time; /* The current game time. Stops when paused. */ +#endif +#ifdef CSQC +float cltime; /* A local timer that ticks relative to local time regardless of latency, packetloss, or pause. */ +#endif +#if defined(CSQC) || defined(SSQC) +float frametime; /* The time since the last physics/render/input frame. */ +#endif +#ifdef CSQC +float player_localentnum; /* This is entity number the player is seeing from/spectating, or the player themself, can change mid-map. */ +float player_localnum; /* The 0-based player index, valid for getplayerkeyvalue calls. */ +float maxclients; /* Maximum number of player slots on the server. */ +float clientcommandframe; /* This is the input-frame sequence. frames < clientcommandframe have been sent to the server. frame==clientcommandframe is still being generated and can still change. */ +float servercommandframe; /* This is the input-frame that was last acknowledged by the server. Input frames greater than this should be applied to the player's entity. */ +#endif +#if defined(QWSSQC) +entity newmis; /* A named entity that should be run soon, to reduce the effects of latency. */ +#endif +#ifdef SSQC +float force_retouch; /* If positive, causes all entities to check for triggers. */ +#endif +#if defined(CSQC) || defined(SSQC) +string mapname; /* The short name of the map. */ +#endif +#if defined(NQSSQC) +float deathmatch; +float coop; +float teamplay; +#endif +#ifdef SSQC +float serverflags; +float total_secrets; +float total_monsters; +float found_secrets; +float killed_monsters; +float parm1; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ +float parm2; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ +float parm3; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ +float parm4; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ +float parm5; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ +float parm6; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ +float parm7; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ +float parm8; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ +float parm9; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ +float parm10; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ +float parm11; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ +float parm12; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ +float parm13; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ +float parm14; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ +float parm15; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ +float parm16; /* Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid. */ +#endif +#ifdef CSQC +float intermission; +#endif +#if defined(CSQC) || defined(SSQC) +vector v_forward; +vector v_up; +vector v_right; +#endif +#ifdef CSQC +vector view_angles; /* +x=DOWN */ +#endif +#if defined(CSQC) || defined(SSQC) +float trace_allsolid; +float trace_startsolid; +float trace_fraction; +vector trace_endpos; +vector trace_plane_normal; +float trace_plane_dist; +entity trace_ent; +float trace_inopen; +float trace_inwater; +#endif +#ifdef CSQC +float input_timelength; +vector input_angles; /* +x=DOWN */ +vector input_movevalues; +float input_buttons; +float input_impulse; +#endif +#ifdef SSQC +entity msg_entity; +void() main; /* This function is never called, and is effectively dead code. */ +void() StartFrame; /* Called at the start of each new physics frame. Player entities may think out of sequence so try not to depend upon explicit ordering too much. */ +void() PlayerPreThink; /* With Prediction(QW compat/FTE default): Called before the player's input commands are processed. +No Prediction(NQ compat): Called AFTER the player's movement intents have already been processed (ie: velocity will have already changed according to input_*, but before the actual position change. */ +void() PlayerPostThink; /* Called after the player's input commands are processed. */ +void() ClientKill; /* Called in response to 'cmd kill' (or just 'kill'). */ +void() ClientConnect; /* Called after the connecting client has finished loading and is ready to receive active entities. Note that this is NOT the first place that a client might be referred to. To determine if the client has csqc active (and kick anyone that doesn't), you can use if(infokeyf(self,INFOKEY_P_CSQCACTIVE)) {sprint(self, "CSQC is required for this server\n");dropclient(self);} */ +void() PutClientInServer; /* Enginewise, this is only ever called immediately after ClientConnect and is thus a little redundant. Modwise, this is also called for respawning a player etc. */ +void() ClientDisconnect; /* Called once a client disconnects or times out. Not guarenteed to be called on map changes. */ +void() SetNewParms; /* Called without context when a new client initially connects (before ClientConnect is even called). This function is expected to only set the parm* globals so that they can be decoded properly later. You should not rely on 'self' being set. */ +void() SetChangeParms; /* Called for each client on map changes. Should copy various entity fields to the parm* globals. */ +#endif +void end_sys_globals; +#if defined(CSQC) || defined(SSQC) +.float modelindex; /* This is the model precache index for the model that was set on the entity, instead of having to look up the model according to the .model field. Use setmodel to change it. */ +.vector absmin; /* Set by the engine when the entity is relinked (by setorigin, setsize, or setmodel). This is in world coordinates. */ +.vector absmax; /* Set by the engine when the entity is relinked (by setorigin, setsize, or setmodel). This is in world coordinates. */ +#endif +#ifdef SSQC +.float ltime; /* On MOVETYPE_PUSH entities, this is used as an alternative to the 'time' global, and .nextthink is synced to this instead of time. This allows time to effectively freeze if the entity is blocked, ensuring the think happens when the entity reaches the target point instead of randomly. */ +#endif +#ifdef CSQC +.float entnum; /* The entity number as its known on the server. */ +.float drawmask; /* Acts as a filter in the addentities call. */ +.float() predraw; /* Called by addentities after the filter and before the entity is actually drawn. Do your interpolation and animation in here. Should return one of the PREDRAW_* constants. */ +#endif +#if defined(QWSSQC) +.float lastruntime; /* This field used to be used to avoid running an entity multiple times in a single frame due to quakeworld's out-of-order thinks. It is no longer used by FTE due to precision issues, but may still be updated for compatibility reasons. */ +#endif +#if defined(CSQC) || defined(SSQC) +.float movetype; /* Describes how the entity moves. One of the MOVETYPE_ constants. */ +.float solid; /* Describes whether the entity is solid or not, and any special properties infered by that. Must be one of the SOLID_ constants */ +.vector origin; /* The current location of the entity in world space. Inline bsp entities (ie: ones placed by a mapper) will typically have a value of '0 0 0' in their neutral pose, as the geometry is offset from that. It is the reference point of the entity rather than the center of its geometry, for non-bsp models, this is often not a significant distinction. */ +.vector oldorigin; /* This is often used on players to reset the player back to where they were last frame if they somehow got stuck inside something due to fpu precision. Never change a player's oldorigin field to inside a solid, because that might cause them to become pemanently stuck. */ +.vector velocity; /* The direction and speed that the entity is moving in world space. */ +.vector angles; /* The eular angles the entity is facing in, in pitch, yaw, roll order. Due to a legacy bug, mdl/iqm/etc formats use +x=UP, bsp/spr/etc formats use +x=DOWN. */ +.vector avelocity; /* The amount the entity's angles change by per second. Note that this is direct eular angles, and thus the angular change is non-linear and often just looks buggy if you're changing more than one angle at a time. */ +#endif +#ifdef CSQC +.float pmove_flags; +#endif +#if defined(NQSSQC) +.vector punchangle; +#endif +#if defined(CSQC) || defined(SSQC) +.string classname; /* Identifies the class/type of the entity. Useful for debugging, also used for loading, but its value is not otherwise significant to the engine, this leaves the mod free to set it to whatever it wants and randomly test strings for values in whatever inefficient way it chooses fit. */ +#endif +#ifdef CSQC +.float renderflags; +#endif +#if defined(CSQC) || defined(SSQC) +.string model; /* The model name that was set via setmodel, in theory. Often, this is cleared to null to prevent the engine from being seen by clients while not changing modelindex. This behaviour allows inline models to remain solid yet be invisible. */ +.float frame; /* The current frame the entity is meant to be displayed in. In CSQC, note the lerpfrac and frame2 fields as well. if it specifies a framegroup, the framegroup will autoanimate in ssqc, but not in csqc. */ +#endif +#ifdef CSQC +.float frame1time; /* The absolute time into the animation/framegroup specified by .frame. */ +.float frame2; /* The alternative frame. Visible only when lerpfrac is set to 1. */ +.float frame2time; /* The absolute time into the animation/framegroup specified by .frame2. */ +.float lerpfrac; /* If 0, use frame1 only. If 1, use frame2 only. Mix them together for values between. */ +#endif +#if defined(CSQC) || defined(SSQC) +.float skin; /* The skin index to use. on a bsp entity, setting this to 1 will switch to the 'activated' texture instead. A negative value will be understood as a replacement contents value, so setting it to CONTENTS_WATER will make a movable pool of water. */ +.float effects; /* Lots of random flags that change random effects. See EF_* constants. */ +.vector mins; /* The minimum extent of the model (ie: the bottom-left coordinate relative to the entity's origin). Change via setsize. May also be changed by setmodel. */ +.vector maxs; /* like mins, but in the other direction. */ +.vector size; /* maxs-mins. Updated when the entity is relinked (by setorigin, setsize, setmodel) */ +.void() touch; +#endif +#ifdef SSQC +.void() use; +#endif +#if defined(CSQC) || defined(SSQC) +.void() think; +.void() blocked; +.float nextthink; /* The time at which the entity is next scheduled to fire its think event. For MOVETYPE_PUSH entities, this is relative to that entity's ltime field, for all other entities it is relative to the time gloal. */ +#endif +#ifdef SSQC +.entity groundentity; +.float health; +.float frags; +.float weapon; +.string weaponmodel; +.float weaponframe; +.float currentammo; +.float ammo_shells; +.float ammo_nails; +.float ammo_rockets; +.float ammo_cells; +.float items; +.float takedamage; +#endif +#if defined(CSQC) || defined(SSQC) +.entity chain; +#endif +#ifdef SSQC +.float deadflag; +.vector view_ofs; +.float button0; +.float button1; +.float button2; +.float impulse; +.float fixangle; /* Forces the clientside view angles to change to the value of .angles (has some lag). If set to 1/TRUE, the server will guess whether to send a delta or an explicit angle. If 2, will always send a delta (due to lag between transmission and acknowledgement, this cannot be spammed reliably). If 3, will always send an explicit angle. */ +.vector v_angle; /* The angles a player is viewing. +x is DOWN (pitch, yaw, roll) */ +#endif +#if defined(NQSSQC) +.float idealpitch; +#endif +#ifdef SSQC +.string netname; +#endif +#if defined(CSQC) || defined(SSQC) +.entity enemy; +.float flags; +.float colormap; +#endif +#ifdef SSQC +.float team; +.float max_health; +.float teleport_time; /* While active, prevents the player from using the +back command, also blocks waterjumping. */ +.float armortype; +.float armorvalue; +.float waterlevel; +.float watertype; +.float ideal_yaw; +.float yaw_speed; +.entity aiment; +.entity goalentity; +.float spawnflags; +.string target; +.string targetname; +.float dmg_take; +.float dmg_save; +.entity dmg_inflictor; +#endif +#if defined(CSQC) || defined(SSQC) +.entity owner; +#endif +#ifdef SSQC +.vector movedir; +.string message; +.float sounds; +.string noise; +.string noise1; +.string noise2; +.string noise3; +#endif +void end_sys_fields; +#ifdef MENU +float time; /* The current local time. Increases while paused. */ +#endif +#if defined(CSQC) || defined(SSQC) +float input_sequence; /* This is the client-generated input sequence number. 0 for unsequenced movements. */ +float input_servertime; /* Server's timestamp of the client's interpolation state. */ +#endif +#ifdef SSQC +float input_timelength; +vector input_angles; /* +x=DOWN */ +vector input_movevalues; +float input_buttons; +float input_impulse; +#endif +#if defined(CSQC) || defined(SSQC) +int trace_endcontents; +int trace_surfaceflags; +int trace_brush_id; +int trace_brush_faceid; +int trace_surface_id; /* 1-based. 0 if not known. */ +int trace_bone_id; /* 1-based. 0 if not known. typically needs MOVE_HITMODEL. */ +int trace_triangle_id; /* 1-based. 0 if not known. */ +#endif +#ifdef CSQC +float trace_networkentity; /* Repots which ssqc entnum was hit when a csqc traceline impacts an ssqc-based brush entity. */ +vector pmove_org; /* Reports the origin of the engineside player (after prediction). Does not work when the player is a csqc-owned entity. */ +vector pmove_vel; /* Reports the velocity of the engineside player (after prediction). Does not work when the player is a csqc-owned entity. */ +float pmove_onground; /* Reports the onground state of the engineside player (after prediction). Does not work when the player is a csqc-owned entity. */ +#endif +#if defined(CSQC) || defined(SSQC) +vector global_gravitydir = '0 0 -1'; /* The direction gravity should act in if not otherwise specified per entity. */ +int serverid; /* The unique id of this server within the server cluster. */ +#endif +#ifdef CSQC +.string message; /* Allows the csqc to read the map description from the server. */ +#endif +#ifdef SSQC +.float button3; +.float button4; +.float button5; +.float button6; +.float button7; +.float button8; +#endif +#if defined(NQSSQC) +.float buttonuse; /* For DP compat only. */ +.float buttonchat; /* For DP compat only. */ +.float cursor_active; /* For DP compat only. */ +.float button9; /* For DP compat only. */ +.float button10; /* For DP compat only. */ +.float button11; /* For DP compat only. */ +.float button12; /* For DP compat only. */ +.float button13; /* For DP compat only. */ +.float button14; /* For DP compat only. */ +.float button15; /* For DP compat only. */ +.float button16; /* For DP compat only. */ +.vector cursor_screen; /* For DP compat only. */ +.vector cursor_start; /* For DP compat only. */ +.vector cursor_impact; /* For DP compat only. */ +.entity cursor_entitynumber; /* For DP compat only. */ +.float lastruntime; /* This field used to be used to avoid running an entity multiple times in a single frame due to quakeworld's out-of-order thinks. It is no longer used by FTE due to precision issues, but may still be updated for compatibility reasons. */ +#endif +#if defined(CSQC) || defined(QWSSQC) +.vector punchangle; +#endif +#if defined(CSQC) || defined(SSQC) +.float gravity; /* Multiplier applied in addition to sv_gravity (not absolute units), to control the gravity affecting this entity specifically. */ +.float hull; /* Overrides the hull used by the entity for walkmove/movetogoal and not traceline/tracebox. */ +.entity movechain; /* This is a linked list of entities which will be moved whenever this entity moves, logically they are attached to this entity. */ +.void() chainmoved; /* Called when the entity is moved as a result of being part of another entity's .movechain */ +.void(float old, float new) contentstransition; /* This function is called when the entity moves between water and air. If specified, default splash sounds will be disabled allowing you to provide your own. */ +.float dimension_solid; /* This is the bitmask of dimensions which the entity is solid within. This is not networked, instead csqc traces impacting ssqc entities assumes the ssqc entity to have a dimension_solid of 1. */ +.float dimension_hit; /* This is the bitmask of dimensions which the entity will be blocked by. If other.dimension_solid & self.dimension_hit, our traces will impact and not proceed. If its false, the traces will NOT impact, allowing self to pass straight through. */ +.int hitcontentsmaski; /* Traces performed for this entity will impact against surfaces that match this contents mask (CONTENTBITS_* constants). */ +__deprecated("Does not support mod-specific contents.") .float dphitcontentsmask; /* Some crappy field that inefficiently requires translating to the native contents flags. Ditch the 'dp', do it properly. */ +.float scale; /* Multiplier that resizes the entity. 1 is normal sized, 2 is double sized. scale 0 is remapped to 1. In SSQC, this is limited to 1/16th precision, with a maximum just shy of 16. */ +.float fatness; /* How many QuakeUnits to push the entity's verticies along their normals by. */ +.float alpha; /* The transparency of the entity. 1 means opaque, 0.0001 means virtually invisible. 0 is remapped to 1, for compatibility. */ +.float modelflags; /* Used to override the flags set in the entity's model. Should be set according to the MF_ constants. Use effects|=EF_NOMODELFLAGS to ignore the model's flags completely. The traileffectnum field is more versatile. */ +#endif +#ifdef SSQC +.float frame1time; /* This controls the time into the framegroup/animation named by .frame, you should increment this value according to frametime or to distance moved, depending on the sort of animation you're attempting. You may wish to avoid incrementing this while lerpfrac is still changing, to avoid wasting parts of the animation. */ +#endif +#if defined(CSQC) || defined(SSQC) +.float basebone; /* The base* frame animations are equivelent to their non-base versions, except that they only affect bone numbers below the 'basebone' value. This means that the base* animation can affect the legs of a skeletal model independantly of the normal animation fields affecting the torso area. For more complex animation than this, use skeletal objects. */ +.float baseframe; /* See basebone */ +.void() customphysics; /* Called once each physics frame, overriding the entity's .movetype field and associated logic. You'll probably want to use tracebox to move it through the world. Be sure to call .think as appropriate. */ +.entity tag_entity; /* Specifies which entity this entity's origin+angles is 'attached' to. */ +.float tag_index; /* Specifies the tag or bone on the parent entity that we're attached to. If this is -1 then the entity is instead a q3-like camera portal, with the tag_entity saying the entity to display for. If tag_entity is world then this is a q3-like portal surface marker with a separate camera (with a tag_entity referring to the portal surface). */ +.float skeletonindex; /* This object serves as a container for the skeletal bone states used to override the animation data. */ +.vector colormod; /* Provides a colour tint for the entity (does not affect fullbrights). */ +.vector glowmod; /* Scaler for an entity's fullbright textures. */ +.vector gravitydir; /* Specifies the direction in which gravity acts. Must be normalised. '0 0 0' also means down. Use '0 0 1' if you want the player to be able to run on ceilings. */ +.vector(vector org, vector ang) camera_transform; /* A callback that provides portal transform information for portal surfaces attached to this entity. Also used to open up pvs in ssqc. */ +#endif +#ifdef SSQC +.float pmove_flags; +#endif +#if defined(CSQC) || defined(SSQC) +.float geomtype; +.float friction; +.float erp; +.float jointtype; +.float mass; +.float bouncefactor; +.float bouncestop; +#endif +#if defined(CSQC) || defined(QWSSQC) +.float idealpitch; +#endif +#if defined(CSQC) || defined(SSQC) +.float pitch_speed; +.float drawflags; /* Various flags that affect lighting values and scaling. Typically set to 96 in quake for proper compatibility with DP_QC_SCALE. */ +.float abslight; /* Allows overriding light levels. Use drawflags to state that this field should actually be used. */ +.vector color; /* This affects the colour of realtime lights that were enabled via the pflags field. */ +.float light_lev; /* This is the radius of an entity's light. This is not normally used by the engine, but is used for realtime lights (ones that are enabled with the pflags field). */ +.float style; /* Used by the light util to decide how an entity's light should animate. On an entity with pflags set, this also affects realtime lights. */ +.float pflags; /* Realtime lighting flags */ +#endif +#ifdef SSQC +.float maxspeed; +.entity view2; /* defines a second viewpoint, typically displayed in a corner of the screen (also punches open pvs). */ +.vector movement; /* These are the directions that the player is currently trying to move in (ie: which +forward/+moveright/+moveup etc buttons they have held), expressed relative to that player's angles. Order is forward, right, up. */ +.float vw_index; /* This acts as a second modelindex, using the same frames etc. */ +__deprecated("Cannot be recorded in MVDs, nor work properly with splitscreen. Use CSQC instead.") .entity nodrawtoclient; /* This entity will not be sent to the player named by this field. They will be invisible and not emit dlights/particles. Does not work in MVD-recorded game. */ +__deprecated("Cannot be recorded in MVDs, nor work properly with splitscreen. Use CSQC instead.") .entity drawonlytoclient; /* This entity will be sent *only* to the player named by this field. To other players they will be invisible and not emit dlights/particles. Does not work in MVD-recorded game. */ +__deprecated("Redundant. Cannot be recorded in MVDs, nor work properly with splitscreen. Use CSQC instead.") .entity viewmodelforclient; /* This entity will be sent only to the player named by this field, and this entity will be attached to the player's view as an additional weapon model. */ +__deprecated("Cannot be recorded in MVDs, nor work properly with splitscreen. Use CSQC instead.") .entity exteriormodeltoclient; /* This entity will be invisible to the player named by this field, except in mirrors or mirror-like surfaces, where it will be visible as normal. It may still cast shadows as normal, and generate lights+particles, depending on client settings. Does not affect how other players see the entity. */ +.entity clientcamera; /* Controls which entity to use for this client's camera. */ +.float glow_size; /* Some outdated particle trail thing. */ +.float glow_color; /* Some outdated particle trail thing. */ +.float glow_trail; /* Some outdated particle trail thing. */ +.float traileffectnum; /* This should be set to the result of particleeffectnum, in order to attach a custom trail effect to an entity as it moves. */ +.float emiteffectnum; /* This should be set to the result of particleeffectnum, in order to continually spawn particles in the direction that this entity faces. */ +__deprecated("Does not work with MVDs nor splitscreen.") .float dimension_see; /* This is the dimension mask (bitfield) that the client is allowed to see. Entities and events not in this dimension mask will be invisible. */ +__deprecated("Does not work with MVDs nor splitscreen.") .float dimension_seen; /* This is the dimension mask (bitfield) that the client is visible within. Clients that cannot see this dimension mask will not see this entity. */ +__deprecated("Does not work with MVDs nor splitscreen.") .float dimension_ghost; /* If this entity is visible only within these dimensions, it will become transparent, as if a ghost. */ +__deprecated("Does not work with MVDs nor splitscreen.") .float dimension_ghost_alpha; /* If this entity is subject to dimension_ghost, this is the scaler for its alpha value. If 0, 0.5 will be used instead. */ +.float(entity playerent, float changedflags) SendEntity; /* Called by the engine whenever an entity needs to be (re)sent to a client's csprogs, either because SendFlags was set or because data was lost. Must write its data to the MSG_ENTITY buffer. Will be called at the engine's leasure. */ +.float SendFlags; /* Indicates that something in the entity has been changed, and that it needs to be updated to all players that can see it. The engine will clear it at some point, with the cleared bits appearing in the 'changedflags' argument of the SendEntity method. */ +__deprecated("Use SendFlags instead.") .float Version; /* Obsolete */ +__deprecated("Doesn't support RGB player colours.") .float clientcolors; +.float viewzoom; +.float playerclass; +.float hasted; +.float light_level; /* Used by hexen2 to indicate the light level where the player is standing. */ +.float pvsflags; /* Reconfigures when the entity is visible to clients */ +.float uniquespawnid; /* Incremented by 1 whenever the entity is respawned. Persists across remove calls, for when the two-second grace period is insufficient. */ +DEP_CSQC .float() customizeentityforclient; /* Called just before an entity is sent to a client (non-csqc protocol). This gives you a chance to tailor 'self' according to what 'other' should see. */ +#endif +#ifdef CSQC +.float frame3; /* Some people just don't understand how to use framegroups... */ +.float frame3time; /* .frame3 equivelent of frame1time. */ +.float lerpfrac3; /* Weight of .frame3 - .frame's weight is automatically calculated as 1-(lerpfrac+lerpfrac3+lerpfrac4), as a result these fields should NEVER add to above 1. */ +.float frame4; +.float frame4time; /* .frame4 equivelent of frame1time. */ +.float lerpfrac4; +.float forceshader; /* Contains a shader handle used to replace all surfaces upon the entity. */ +.float baseframe2; /* See basebone */ +.float baseframe1time; /* See basebone */ +.float baseframe2time; /* See basebone */ +.float baselerpfrac; /* See basebone */ +.float bonecontrol1; /* Halflife model format bone controller. On player models, this typically affects the spine's yaw. */ +.float bonecontrol2; /* Halflife model format bone controller. On player models, this typically affects the spine's yaw. */ +.float bonecontrol3; /* Halflife model format bone controller. On player models, this typically affects the spine's yaw. */ +.float bonecontrol4; /* Halflife model format bone controller. On player models, this typically affects the spine's yaw. */ +.float bonecontrol5; /* Halflife model format bone controller. This typically affects the mouth. */ +.float subblendfrac; /* Weird animation value specific to halflife models. On player models, this typically affects the spine's pitch, or yaw, or... */ +.float subblend2frac; /* Weird animation value specific to halflife models. I've no idea what this does, probably nothing for most models. */ +.float basesubblendfrac; /* See basebone */ +.float basesubblend2frac; /* See basebone */ +#endif +void(float reqid, float responsecode, string resourcebody, int resourcebytes) URI_Get_Callback; /* Called as an eventual result of the uri_get builtin. */ +#ifdef SSQC +void() SpectatorConnect; /* Called when a spectator joins the game. */ +void() SpectatorDisconnect; /* Called when a spectator disconnects from the game. */ +void() SpectatorThink; /* Called each frame for each spectator. */ +void(string cmd) SV_ParseClientCommand; /* Provides QC with a way to intercept 'cmd foo' commands from the client. Very handy. Self will be set to the sending client, while the 'cmd' argument can be tokenize()d and each element retrieved via argv(argno). Unrecognised cmds MUST be passed on to the clientcommand builtin. */ +void(string dest, string from, string cmd, string info) SV_ParseClusterEvent; /* Part of cluster mode. Handles cross-node events that were sent via clusterevent, on behalf of the named client. */ +float(string sender, string body) SV_ParseConnectionlessPacket; /* Provides QC with a way to communicate between servers, or with client server browsers. Sender is the sender's ip. Body is the body of the message. You'll need to add your own password/etc support as required. Self is not valid. */ +void(float pauseduration) SV_PausedTic; /* For each frame that the server is paused, this function will be called to give the gamecode a chance to unpause the server again. the pauseduration argument says how long the server has been paused for (the time global is frozen and will not increment while paused). Self is not valid. */ +float(float newstatus) SV_ShouldPause; /* Called to give the qc a change to block pause/unpause requests. Return false for the pause request to be ignored. newstatus is 1 if the user is trying to pause the game. For the duration of the call, self will be set to the player who tried to pause, or to world if it was triggered by a server-side event. */ +void() SV_RunClientCommand; /* Called each time a player movement packet was received from a client. Self is set to the player entity which should be updated, while the input_* globals specify the various properties stored within the input packet. The contents of this function should be somewaht identical to the equivelent function in CSQC, or prediction misses will occur. If you're feeling lazy, you can simply call 'runstandardplayerphysics' after modifying the inputs. */ +void() SV_AddDebugPolygons; /* Called each video frame. This is the only place where ssqc is allowed to call the R_BeginPolygon/R_PolygonVertex/R_EndPolygon builtins. This is exclusively for debugging, and will break in anything but single player as it will not be called if the engine is not running both a client and a server. */ +DEP_CSQC void() SV_PlayerPhysics; /* Compatibility method to tweak player input that does not reliably work with prediction (prediction WILL break). Mods that care about prediction should use SV_RunClientCommand instead. If pr_no_playerphysics is set to 1, this function will never be called, which will either fix prediction or completely break player movement depending on whether the feature was even useful. */ +void(float fd, float entcount, float playerslots) SV_PerformSave; /* Called by the engine as part of saved games. The QC is responsible for writing any data that will be required to restore the game. Save files are not limited to just text, you can use fwrite (and later fread) for binary data. Remember to close the passed file. */ +void(float fd, float entcount, float playerslots) SV_PerformLoad; /* Called by the engine to restore a saved game that was saved via SV_PerformSave, the server will have already started the game to its inital state (for precaches+makestatic calls), so entities+globals will have their post-spawn values (you will likely want to remove most of them, you can use the two extra args as helpers for that). You can use respawn_edict to un-remove specific entities, with parseentitydata or putentityfieldstring(findentityfield(NAME), ent, value) to assign to fields by name strings. Don't expect bprints/etc to work - players are likely in a pending state. Remember to close the passed file. */ +void() RestoreGame; /* Called for each reconnecting player as part of loading a saved game. Part of NEH_RESTOREGAME. */ +void() EndFrame; /* Called after non-player entities have been run at the end of the physics frame. Player physics is performed out of order and can/will still occur between EndFrame and BeginFrame. */ +void() SetTransferParms; /* Called as an alternative to SetChangeParms when a player is transferring to another server. Part of FTE_SV_CLUSTER. */ +string(string addr, string uinfo, string features) SV_CheckRejectConnection; /* Called to give the mod a chance to ignore connection requests based upon client protocol support or other properties. Use infoget to read the uinfo and features arguments. */ +#endif +#ifdef CSQC +void(float apilevel, string enginename, float engineversion) CSQC_Init; /* Called at startup. enginename and engineversion are arbitary hints and can take any form. enginename should be consistant between revisions, but this cannot truely be relied upon. */ +void() CSQC_WorldLoaded; /* Called after the server's model+sound precaches have been executed. Gives a chance for the qc to read the entity lump from the bsp (via getentitytoken). */ +void() CSQC_Shutdown; /* Specifies that the csqc is going down. Save your persistant settings here. */ +void(float vwidth, float vheight, float notmenu) CSQC_UpdateView; /* Called every single video frame. The CSQC is responsible for rendering the entire screen. */ +void(float vwidth, float vheight, float notmenu) CSQC_UpdateViewLoading; /* Alternative to CSQC_UpdateView, called when the engine thinks there should be a loading screen. If present, will inhibit the engine's normal loading screen, deferring to qc to draw it. */ +void(vector viewsize, float scoresshown) CSQC_DrawHud; /* Part of simple csqc, called after drawing the 3d view whenever CSQC_UpdateView is not defined. */ +void(vector viewsize, float scoresshown) CSQC_DrawScores; /* Part of simple csqc, called after CSQC_DrawHud whenever CSQC_UpdateView is not defined, and when there are no menus/console active. */ +void(string msg) CSQC_Parse_StuffCmd; /* Gives the CSQC a chance to intercept stuffcmds. Use the tokenize builtin to parse the message. Unrecognised commands would normally be localcmded, but its probably better to drop unrecognised stuffcmds completely. */ +float(string msg) CSQC_Parse_CenterPrint; /* Gives the CSQC a chance to intercept centerprints. Return true if you wish the engine to otherwise ignore the centerprint. */ +float(float save, float take, vector inflictororg) CSQC_Parse_Damage; /* Called as a result of player.dmg_save or player.dmg_take being set on the server. +Return true to completely inhibit the engine's colour shift and damage rolls, allowing you to do your own thing. +You can use punch_roll += (normalize(inflictororg-player.origin)*v_right)*(take+save)*autocvar_v_kickroll; as a modifier for the roll angle should the player be hit from the side, and slowly fade it away over time. */ +void(string printmsg, float printlvl) CSQC_Parse_Print; /* Gives the CSQC a chance to intercept sprint/bprint builtin calls. CSQC should filter by the client's current msg setting and then pass the message on to the print command, or handle them itself. */ +void() CSQC_Parse_Event; /* Called when the client receives an SVC_CGAMEPACKET. The csqc should read the data or call the error builtin if it does not recognise the message. */ +float(float evtype, float scanx, float chary, float devid) CSQC_InputEvent; /* Called whenever a key is pressed, the mouse is moved, etc. evtype will be one of the IE_* constants. The other arguments vary depending on the evtype. Key presses are not guarenteed to have both scan and unichar values set at the same time. */ +__used void() CSQC_Input_Frame; /* Called just before each time clientcommandframe is updated. You can edit the input_* globals in order to apply your own player inputs within csqc, which may allow you a convienient way to pass certain info to ssqc. */ +void(string rendererdescription) CSQC_RendererRestarted; /* Called by the engine after the video was restarted. This serves to notify the CSQC that any render targets that it may have cached were purged, and will need to be regenerated. */ +float(string cmd) CSQC_ConsoleCommand; /* Called if the user uses any console command registed via registercommand. */ +float(string text, string info) CSQC_ConsoleLink; /* Called if the user clicks a ^[text\infokey\infovalue^] link. Use infoget to read/check each supported key. Return true if you wish the engine to not attempt to handle the link itself. +WARNING: link text can potentially come from other players, so be careful about what you allow to be changed. */ +void(float entnum) CSQC_Ent_Spawn; /* Clumsily defined function for compat with DP. Should call spawn, set that ent's entnum field, and return the entity inside the 'self' global which will then be used for fllowing Ent_Updates. MUST NOT PARSE ANY NETWORK DATA (which makes it kinda useless). */ +void(float isnew) CSQC_Ent_Update; /* Parses the data sent by ssqc's various SendEntity functions (must use the exact same reads as the ssqc used writes - to debug this rule more easily, you may wish to use sv_csqcdebug). 'self' provides context between frames, and self.entnum should normally report which ssqc entity . Be aware that interpolation will need to happen separately. */ +void() CSQC_Ent_Remove; +float(float entnum, float channel, string soundname, float vol, float attenuation, vector pos, float pitchmod, float flags) CSQC_Event_Sound; +float() CSQC_Parse_TempEntity; /* Please don't use this. Use CSQC_Parse_Event and multicasts instead. +The use of serverside protocol translation to handle QW vs NQ protocols mean that you're likely to end up reading slightly different data. Which is bad. +Return true to say that you fully handled the tempentity. Return false to have the client attempt to rewind the network stream and parse the message itself. */ +#endif +#if defined(CSQC) || defined(MENU) +void(string cmdtext) GameCommand; +#endif +string(string uri, string method, string postdata, __in string requestheaders, __inout string responseheaders) Cef_GeneratePage; /* Provides an entrypoint to generate pages for the CEF plugin from within QC. Headers are +-separated key/value pairs (use tokenizebyseparator). */ +#ifdef SSQC string(string uri, string method, string postdata, __in string requestheaders, __inout string responseheaders) HTTP_GeneratePage; /* Provides an entrypoint to generate pages for pages requested over http (sv_port_tcp+net_enable_http). Headers are --separated key/value pairs (use tokenizebyseparator). Return __NULL__ to let the engine handle it, an empty string for a 404, and any other text for a regular 200 response. */ -#endif -#if defined(CSQC) || defined(SSQC) -void(float prevprogs) init; /* Part of FTE_MULTIPROGS. Called as soon as a progs is loaded, called at a time when entities are not valid. This is the only time when it is safe to call addprogs without field assignment. As it is also called as part of addprogs, this also gives you a chance to hook functions in modules that are already loaded (via externget+externget). */ -void() initents; /* Part of FTE_MULTIPROGS. Called after fields have been finalized. This is the first point at which it is safe to call spawn(), and is called before any entity fields have been parsed. You can use this entrypoint to send notifications to other modules. */ -#endif -#ifdef MENU -void() m_init; -void() m_shutdown; -void(vector screensize) m_draw; /* Provides the menuqc with a chance to draw. Will be called even if the menu does not have focus, so be sure to avoid that. COMPAT: screensize is not provided in DP. */ -void(vector screensize, float opaque) m_drawloading; /* Additional drawing function to draw loading screens. If opaque is set, then this function must ensure that the entire screen is overdrawn (even if just by a black drawfill). */ -void(string rendererdescription) Menu_RendererRestarted; /* Called by the engine after the video was restarted. This serves to notify the MenuQC that any render targets that it may have cached were purged, and will need to be regenerated. */ -float(float evtype, float scanx, float chary, float devid) Menu_InputEvent; /* If present, this is called instead of m_keydown and m_keyup -Called whenever a key is pressed, the mouse is moved, etc. evtype will be one of the IE_* constants. The other arguments vary depending on the evtype. Key presses are not guarenteed to have both scan and unichar values set at the same time. */ -__deprecated("Use Menu_InputEvent") void(float scan, float chr) m_keydown; -__deprecated("Use Menu_InputEvent") void(float scan, float chr) m_keyup; -void(float wantmode) m_toggle; -float(string cmd) m_consolecommand; -float(float idx) m_gethostcachecategory; -#endif -#ifdef SSQC -float parm17, parm18, parm19, parm20, parm21, parm22, parm23, parm24, parm25, parm26, parm27, parm28, parm29, parm30, parm31, parm32; /* Additional spawn parms, following the same parmN theme. */ -float parm33, parm34, parm35, parm36, parm37, parm38, parm39, parm40, parm41, parm42, parm43, parm44, parm45, parm46, parm47, parm48; -float parm49, parm50, parm51, parm52, parm53, parm54, parm55, parm56, parm57, parm58, parm59, parm60, parm61, parm62, parm63, parm64; -string parm_string; /* Like the regular parmN globals, but preserves string contents. */ -string startspot; /* Receives the value of the second argument to changelevel from the previous map. */ -var float dimension_send; /* Used by multicast functionality. Multicasts (and related builtins that multicast internally) will only be sent to players where (player.dimension_see & dimension_send) is non-zero. */ -//var float dimension_default = 255; -/* Default dimension bitmask */ -__unused var string __fullspawndata; /* Set by the engine before calls to spawn functions, and is most easily parsed with the tokenize builtin. This allows you to handle halflife's multiple-fields-with-the-same-name (or target-specific fields). */ -#endif -#if defined(CSQC) || defined(SSQC) -__used var float physics_mode = 2; /* 0: original csqc - physics are not run -1: DP-compat. Thinks occur, but not true movetypes. -2: movetypes occur just as they do in ssqc. */ -#endif -#ifdef CSQC -float gamespeed; /* Set by the engine, this is the value of the sv_gamespeed cvar */ -float numclientseats; /* This is the number of splitscreen clients currently running on this client. */ -#endif -#if defined(CSQC) || defined(MENU) -var vector drawfontscale = '1 1 0'; /* Specifies a scaler for all text rendering. There are other ways to implement this. */ -float drawfont; /* Allows you to choose exactly which font is to be used to draw text. Fonts can be registered/allocated with the loadfont builtin. */ -const float FONT_DEFAULT = 0; -#endif -#if defined(NQSSQC) -entity newmis; /* ssqc global */ -#endif -#if defined(CSQC) || defined(QWSSQC) -float deathmatch; /* ssqc global */ -float coop; /* ssqc global */ -#endif -#if defined(QWSSQC) -float teamplay; /* ssqc global */ -#endif -#if defined(CSQC) || defined(SSQC) -int trace_endcontentsi; /* ssqc global */ -int trace_surfaceflagsi; /* ssqc global */ -string trace_surfacename; /* ssqc global */ -float cycle_wrapped; /* ssqc global */ -#endif -#ifdef CSQC -float dimension_default; /* ssqc global */ -#endif -#if defined(CSQC) || defined(SSQC) -unsigned int input_weapon; /* ssqc global */ -float input_lightlevel; /* ssqc global */ -vector input_cursor_screen; /* ssqc global */ -vector input_cursor_trace_start; /* ssqc global */ -vector input_cursor_trace_endpos; /* ssqc global */ -float input_cursor_entitynumber; /* ssqc global */ -unsigned int input_head_status; /* ssqc global */ -vector input_head_origin; /* ssqc global */ -vector input_head_angles; /* ssqc global */ -vector input_head_velocity; /* ssqc global */ -vector input_head_avelocity; /* ssqc global */ -unsigned int input_head_weapon; /* ssqc global */ -unsigned int input_left_status; /* ssqc global */ -vector input_left_origin; /* ssqc global */ -vector input_left_angles; /* ssqc global */ -vector input_left_velocity; /* ssqc global */ -vector input_left_avelocity; /* ssqc global */ -unsigned int input_left_weapon; /* ssqc global */ -unsigned int input_right_status; /* ssqc global */ -vector input_right_origin; /* ssqc global */ -vector input_right_angles; /* ssqc global */ -vector input_right_velocity; /* ssqc global */ -vector input_right_avelocity; /* ssqc global */ -unsigned int input_right_weapon; /* ssqc global */ -#endif -#ifdef SSQC -float trace_endcontentsf; /* ssqc global */ -float trace_surfaceflagsf; /* ssqc global */ -#endif -#if defined(CSQC) || defined(SSQC) -string trace_dphittexturename; /* ssqc global */ -#endif -#ifdef SSQC -float trace_dpstartcontents; /* ssqc global */ -float trace_dphitcontents; /* ssqc global */ -float trace_dphitq3surfaceflags; /* ssqc global */ -#endif -#ifdef CSQC -float(vector angles, float isdelta) CSQC_Parse_SetAngles; -void(float playernum) CSQC_PlayerInfoChanged; -void() CSQC_ServerInfoChanged; -DEP("use CSQC_Event_Sound") float(float channel, string soundname, vector pos, float vol, float attenuation, float flags) CSQC_ServerSound; -void(int entidx, string newentdata) CSQC_MapEntityEdited; -float clframetime; -float servertime; -float serverprevtime; -float serverdeltatime; -DEP("Does not support mod-specific contents.") float trace_dpstartcontents; -DEP("Does not support mod-specific contents.") float trace_dphitcontents; -DEP("Does not support mod-specific surface flags") float trace_dphitq3surfaceflags; -DEP("Does not support all mod-specific surface flags.") float trace_surfaceflagsf; -DEP("Does not support all mod-specific contents.") float trace_endcontentsf; -float intermission_time; -vector pmove_mins; -vector pmove_maxs; -float pmove_jump_held; -float pmove_waterjumptime; -float input_clienttime; -float autocvar_vid_conwidth; -float autocvar_vid_conheight; -#endif -const float TRUE = 1; -const float FALSE = 0; /* File not found... */ -const float M_PI = 3.14159; /* Mathematica Pi constant. */ -#if defined(CSQC) || defined(SSQC) -const float MOVETYPE_NONE = 0; -const float MOVETYPE_WALK = 3; -const float MOVETYPE_STEP = 4; -const float MOVETYPE_FLY = 5; -const float MOVETYPE_TOSS = 6; -const float MOVETYPE_PUSH = 7; -const float MOVETYPE_NOCLIP = 8; -const float MOVETYPE_FLYMISSILE = 9; -const float MOVETYPE_BOUNCE = 10; -const float MOVETYPE_BOUNCEMISSILE = 11; -const float MOVETYPE_FOLLOW = 12; -const float MOVETYPE_6DOF = 30; /* A glorified MOVETYPE_FLY. Players using this movetype will get some flightsim-like physics, with fully independant rotations (order-dependant transforms). */ -const float MOVETYPE_WALLWALK = 31; /* Players using this movetype will be able to orient themselves to walls, and then run up them. */ -const float MOVETYPE_PHYSICS = 32; /* Enable the use of ODE physics upon this entity. */ -const float SOLID_NOT = 0; -const float SOLID_TRIGGER = 1; -const float SOLID_BBOX = 2; -const float SOLID_SLIDEBOX = 3; -const float SOLID_BSP = 4; /* Does not collide against other SOLID_BSP entities. Normally paired with MOVETYPE_PUSH. */ -const float SOLID_CORPSE = 5; /* Non-solid to SOLID_SLIDEBOX or other SOLID_CORPSE entities. For hitscan weapons to hit corpses, change the player's .hitcontentsmaski value to include CONTENTBIT_CORPSE, perform the traceline, then revert the player's .solid value. */ -__deprecated("Obsoleted by .skin=CONTENTS_LADDER") const float SOLID_LADDER = 20; /* Obsolete and may be removed at some point. Use skin=CONTENT_LADDER and solid_bsp or solid_trigger instead. */ -const float SOLID_PORTAL = 21; /* CSG subtraction volume combined with entity transformations on impact. */ -const float SOLID_BSPTRIGGER = 22; /* For complex-shaped trigger volumes, instead of being a pure aabb. */ -const float SOLID_PHYSICS_BOX = 32; -const float SOLID_PHYSICS_SPHERE = 33; -const float SOLID_PHYSICS_CAPSULE = 34; -const float SOLID_PHYSICS_TRIMESH = 35; -const float SOLID_PHYSICS_CYLINDER = 36; -const float GEOMTYPE_NONE = -1; -const float GEOMTYPE_SOLID = 0; -const float GEOMTYPE_BOX = 1; -const float GEOMTYPE_SPHERE = 2; -const float GEOMTYPE_CAPSULE = 3; -const float GEOMTYPE_TRIMESH = 4; -const float GEOMTYPE_CYLINDER = 5; -const float GEOMTYPE_CAPSULE_X = 6; -const float GEOMTYPE_CAPSULE_Y = 7; -const float GEOMTYPE_CAPSULE_Z = 8; -const float GEOMTYPE_CYLINDER_X = 9; -const float GEOMTYPE_CYLINDER_Y = 10; -const float GEOMTYPE_CYLINDER_Z = 11; -const float JOINTTYPE_FIXED = -1; -const float JOINTTYPE_POINT = 1; -const float JOINTTYPE_HINGE = 2; -const float JOINTTYPE_SLIDER = 3; -const float JOINTTYPE_UNIVERSAL = 4; -const float JOINTTYPE_HINGE2 = 5; -#endif -#ifdef CSQC -const float GE_MAXENTS = -1; /* Valid for getentity, ignores the entity argument. Returns the maximum number of entities which may be valid, to avoid having to poll 65k when only 100 are used. */ -const float GE_ACTIVE = 0; /* Valid for getentity. Returns whether this entity is known to the client or not. */ -const float GE_ORIGIN = 1; /* Valid for getentity. Returns the interpolated .origin. */ -const float GE_FORWARD = 2; /* Valid for getentity. Returns the interpolated forward vector. */ -const float GE_RIGHT = 3; /* Valid for getentity. Returns the entity's right vector. */ -const float GE_UP = 4; /* Valid for getentity. Returns the entity's up vector. */ -const float GE_SCALE = 5; /* Valid for getentity. Returns the entity .scale. */ -const float GE_ORIGINANDVECTORS = 6; /* Valid for getentity. Returns interpolated .origin, but also sets v_forward, v_right, and v_up accordingly. Use vectoangles(v_forward,v_up) to determine the angles. */ -const float GE_ALPHA = 7; /* Valid for getentity. Returns the entity alpha. */ -const float GE_COLORMOD = 8; /* Valid for getentity. Returns the colormod vector. */ -const float GE_PANTSCOLOR = 9; /* Valid for getentity. Returns the entity's lower color (from .colormap), as a palette range value. */ -const float GE_SHIRTCOLOR = 10; /* Valid for getentity. Returns the entity's lower color (from .colormap), as a palette range value. */ -const float GE_SKIN = 11; /* Valid for getentity. Returns the entity's .skin index. */ -const float GE_MINS = 12; /* Valid for getentity. Guesses the entity's .min vector. */ -const float GE_MAXS = 13; /* Valid for getentity. Guesses the entity's .max vector. */ -const float GE_ABSMIN = 14; /* Valid for getentity. Guesses the entity's .absmin vector. */ -const float GE_ABSMAX = 15; /* Valid for getentity. Guesses the entity's .absmax vector. */ -const float GE_MODELINDEX = 200; /* Valid for getentity. Guesses the entity's .modelindex float. */ -const float GE_MODELINDEX2 = 201; /* Valid for getentity. Guesses the entity's .vw_index float. */ -const float GE_EFFECTS = 202; /* Valid for getentity. Guesses the entity's .effects float. */ -const float GE_FRAME = 203; /* Valid for getentity. Guesses the entity's .frame float. */ -const float GE_ANGLES = 204; /* Valid for getentity. Guesses the entity's .angles vector. */ -const float GE_FATNESS = 205; /* Valid for getentity. Guesses the entity's .fatness float. */ -const float GE_DRAWFLAGS = 206; /* Valid for getentity. Guesses the entity's .drawflags float. */ -const float GE_ABSLIGHT = 207; /* Valid for getentity. Guesses the entity's .abslight float. */ -const float GE_GLOWMOD = 208; /* Valid for getentity. Guesses the entity's .glowmod vector. */ -const float GE_GLOWSIZE = 209; /* Valid for getentity. Guesses the entity's .glowsize float. */ -const float GE_GLOWCOLOUR = 210; /* Valid for getentity. Guesses the entity's .glowcolor float. */ -const float GE_RTSTYLE = 211; /* Valid for getentity. Guesses the entity's .style float. */ -const float GE_RTPFLAGS = 212; /* Valid for getentity. Guesses the entity's .pflags float. */ -const float GE_RTCOLOUR = 213; /* Valid for getentity. Guesses the entity's .color vector. */ -const float GE_RTRADIUS = 214; /* Valid for getentity. Guesses the entity's .light_lev float. */ -const float GE_TAGENTITY = 215; /* Valid for getentity. Guesses the entity's .tag_entity float. */ -const float GE_TAGINDEX = 216; /* Valid for getentity. Guesses the entity's .tag_index float. */ -const float GE_GRAVITYDIR = 217; /* Valid for getentity. Guesses the entity's .gravitydir vector. */ -const float GE_TRAILEFFECTNUM = 218; /* Valid for getentity. Guesses the entity's .traileffectnum float. */ -#endif -#ifdef SSQC -const float DAMAGE_NO = 0; -const float DAMAGE_YES = 1; -const float DAMAGE_AIM = 2; -#endif -#if defined(CSQC) || defined(SSQC) -const float CONTENT_EMPTY = -1; -const float CONTENT_SOLID = -2; -const float CONTENT_WATER = -3; -const float CONTENT_SLIME = -4; -const float CONTENT_LAVA = -5; -const float CONTENT_SKY = -6; -const float CONTENT_LADDER = -16; /* If this value is assigned to a solid_bsp's .skin field, the entity will become a ladder volume. */ -const int CONTENTBIT_NONE = 0x00000000i; -const int CONTENTBIT_SOLID = 0x00000001i; -const int CONTENTBIT_LAVA = 0x00000008i; -const int CONTENTBIT_SLIME = 0x00000010i; -const int CONTENTBIT_WATER = 0x00000020i; -const int CONTENTBIT_FTELADDER = 0x00004000i; /* Content bit used for .skin=CONTENT_LADDER entities. */ -const int CONTENTBIT_PLAYERCLIP = 0x00010000i; -const int CONTENTBIT_MONSTERCLIP = 0x00020000i; -const int CONTENTBIT_BODY = 0x02000000i; /* Content bit that indicates collisions against SOLID_BBOX/SOLID_SLIDEBOX entities. */ -const int CONTENTBIT_CORPSE = 0x04000000i; /* Content bit that indicates collisions against SOLID_CORPSE entities. */ -const int CONTENTBIT_Q2LADDER = 0x20000000i; /* Content bit specific to q2bsp (conflicts with q3bsp contents so use with caution). */ -const int CONTENTBIT_SKY = 0x80000000i; /* Content bit somewhat specific to q1bsp (aliases to NODROP in q3bsp), but you should probably check surfaceflags&SURF_SKY as well for q2+q3bsp too. */ -const int CONTENTBITS_POINTSOLID = CONTENTBIT_SOLID|0x00000002i|CONTENTBIT_BODY; /* Bits that traceline would normally consider solid */ -const int CONTENTBITS_BOXSOLID = CONTENTBIT_SOLID|0x00000002i|CONTENTBIT_BODY|CONTENTBIT_PLAYERCLIP; /* Bits that tracebox would normally consider solid */ -const int CONTENTBITS_FLUID = CONTENTBIT_WATER|CONTENTBIT_SLIME|CONTENTBIT_LAVA|CONTENTBIT_SKY; -const float SPA_POSITION = 0; /* These SPA_* constants are to specify which attribute is returned by the getsurfacepointattribute builtin */ -const float SPA_S_AXIS = 1; -const float SPA_T_AXIS = 2; -const float SPA_R_AXIS = 3; /* aka: SPA_NORMAL */ -const float SPA_TEXCOORDS0 = 4; -const float SPA_LIGHTMAP0_TEXCOORDS = 5; -const float SPA_LIGHTMAP0_COLOR = 6; -const float CHAN_AUTO = 0; /* The automatic channel, play as many sounds on this channel as you want, and they'll all play, however the other channels will replace each other. */ -const float CHAN_WEAPON = 1; -const float CHAN_VOICE = 2; -const float CHAN_ITEM = 3; -const float CHAN_BODY = 4; -#endif -#if defined(QWSSQC) -const float CHANF_RELIABLE = 8; /* Only valid if the flags argument is not specified. The sound will be sent reliably, which is important if it is intended to replace looping sounds on doors etc. */ -#endif -#ifdef SSQC -const float SOUNDFLAG_RELIABLE = 1; /* The sound will be sent reliably, and without regard to phs. */ -#endif -#ifdef CSQC -const float SOUNDFLAG_ABSVOLUME = 16; /* The sample's volume is not scaled by the volume cvar. Use with caution */ -#endif -#if defined(CSQC) || defined(SSQC) -const float SOUNDFLAG_FORCELOOP = 2; /* The sound will restart once it reaches the end of the sample. */ -const float SOUNDFLAG_NOSPACIALISE = 4; /* The different audio channels are played at the same volume regardless of which way the player is facing, without needing to use 0 attenuation. */ -const float SOUNDFLAG_NOREVERB = 32; /* Disables the use of underwater/reverb effects on this sound effect. */ -const float SOUNDFLAG_FOLLOW = 64; /* The sound's origin will updated to follow the emitting entity. */ -const float SOUNDFLAG_NOREPLACE = 128; /* Sounds started with this flag will be ignored when there's already a sound playing on that same ent-channel. */ -#endif -#ifdef SSQC -const float SOUNDFLAG_UNICAST = 256; /* The sound will be sent only by the player specified by msg_entity. Spectators and related splitscreen players will also hear the sound. */ -const float SOUNDFLAG_SENDVELOCITY = 512; /* The entity's current velocity will be sent to the client, only useful if doppler is enabled. */ -#endif -#if defined(CSQC) || defined(SSQC) -const float ATTN_NONE = 0; /* Sounds with this attenuation can be heard throughout the map */ -const float ATTN_NORM = 1; /* Standard attenuation */ -const float ATTN_IDLE = 2; /* Extra attenuation so that sounds don't travel too far. */ -const float ATTN_STATIC = 3; /* Even more attenuation to avoid torches drowing out everything else throughout the map. */ -#endif -#ifdef SSQC -const float SVC_CGAMEPACKET = 83; /* Direct ssqc->csqc message. Must only be multicast. The data triggers a CSQC_Parse_Event call in the csqc for the csqc to read the contents. The server *may* insert length information for clients connected via proxies which are not able to cope with custom csqc payloads. This should only ever be used in conjunction with the MSG_MULTICAST destination. */ -#endif -#if defined(CSQC) || defined(SSQC) -const float TE_SPIKE = 0; -const float TE_SUPERSPIKE = 1; -const float TE_GUNSHOT = 2; -const float TE_EXPLOSION = 3; -const float TE_TAREXPLOSION = 4; -const float TE_LIGHTNING1 = 5; -const float TE_LIGHTNING2 = 6; -const float TE_WIZSPIKE = 7; -const float TE_KNIGHTSPIKE = 8; -const float TE_LIGHTNING3 = 9; -const float TE_LAVASPLASH = 10; -const float TE_TELEPORT = 11; -#endif -#if defined(CSQC) || defined(QWSSQC) -const float TE_BLOOD = 12; -#endif -#if defined(NQSSQC) -const float TE_EXPLOSION2 = 12; -#endif -#if defined(CSQC) || defined(QWSSQC) -const float TE_LIGHTNINGBLOOD = 13; -#endif -#if defined(NQSSQC) -const float TE_BEAM = 13; -const float MSG_BROADCAST = 0; /* The byte(s) will be unreliably sent to all players. MSG_ constants are valid arguments to the Write* builtin family. */ -const float MSG_ONE = 1; /* The byte(s) will be reliably sent to the player specified in the msg_entity global. WARNING: in quakeworld servers without network preparsing enabled, this can result in illegible server messages (due to individual reliable messages being split between multiple backbuffers/packets). NQ has larger reliable buffers which avoids this issue, but still kicks the client. */ -const float MSG_ALL = 2; /* The byte(s) will be reliably sent to all players. */ -#endif -#if defined(QWSSQC) -__deprecated("Use MSG_MULTICAST+multicast(MULTICAST_*)") const float MSG_BROADCAST; /* The byte(s) will be unreliably sent to all players. MSG_ constants are valid arguments to the Write* builtin family. */ -__deprecated("Use MSG_MULTICAST+multicast(MULTICAST_ONE_R)") const float MSG_ONE = 1; /* The byte(s) will be reliably sent to the player specified in the msg_entity global. WARNING: in quakeworld servers without network preparsing enabled, this can result in illegible server messages (due to individual reliable messages being split between multiple backbuffers/packets). NQ has larger reliable buffers which avoids this issue, but still kicks the client. */ -__deprecated("Use MSG_MULTICAST+multicast(MULTICAST_ALL)") const float MSG_ALL = 2; /* The byte(s) will be reliably sent to all players. */ -#endif -#ifdef SSQC -const float MSG_INIT = 3; /* The byte(s) will be written into the signon buffer. Clients will see these messages when they connect later. This buffer is only flushed on map changes, so spamming it _WILL_ result in overflows. */ -const float MSG_MULTICAST = 4; /* The byte(s) will be written into the multicast buffer for more selective sending. Messages sent this way will never be split across packets, and using this for csqc-only messages will not break protocol translation. */ -const float MSG_ENTITY = 5; /* The byte(s) will be written into the entity buffer. This is a special value used only inside 'SendEntity' functions. */ -const float MULTICAST_ALL = 0; /* The multicast message is unreliably sent to all players. MULTICAST_ constants are valid arguments for the multicast builtin, which ignores the specified origin when given this constant. */ -const float MULTICAST_PHS = 1; /* The multicast message is unreliably sent to only players that can potentially hear the specified origin. Its quite loose. */ -const float MULTICAST_PVS = 2; /* The multicast message is unreliably sent to only players that can potentially see the specified origin. */ -const float MULTICAST_ONE = 6; /* The multicast message is unreliably sent to the player (AND ALL TRACKING SPECTATORS) specified in the msg_entity global. The specified origin is ignored. */ -const float MULTICAST_ONE_NOSPECS = 9; /* The multicast message is unreliably sent to the player specified in the msg_entity global. The specified origin is ignored. */ -const float MULTICAST_ALL_R = 3; /* The multicast message is reliably sent to all players. The specified origin is ignored. */ -const float MULTICAST_PHS_R = 4; /* The multicast message is reliably sent to only players that can potentially hear the specified origin. Players might still not receive it if they are out of range. */ -const float MULTICAST_PVS_R = 5; /* The multicast message is reliably sent to only players that can potentially see the specified origin. Players might still not receive it if they cannot see the event. */ -const float MULTICAST_ONE_R = 7; /* The multicast message is reliably sent to the player (AND ALL TRACKING SPECTATORS) specified in the msg_entity global. The specified origin is ignored */ -const float MULTICAST_ONE_R_NOSPECS = 10; /* The multicast message is reliably sent to the player specified in the msg_entity global. The specified origin is ignored */ -#endif -#if defined(QWSSQC) -const float PRINT_LOW = 0; -const float PRINT_MEDIUM = 1; -const float PRINT_HIGH = 2; -const float PRINT_CHAT = 3; -#endif -#ifdef SSQC -const float PVSF_NORMALPVS = 0; /* Filter first by PVS, then filter this entity using tracelines if sv_cullentities is enabled. */ -const float PVSF_NOTRACECHECK = 1; /* Filter strictly by PVS. */ -const float PVSF_USEPHS = 2; /* Send if we're close enough to be able to hear this entity. */ -const float PVSF_IGNOREPVS = 3; /* Ignores pvs. This entity is visible whereever you are on the map. Updates will be sent regardless of pvs or phs */ -const float PVSF_NOREMOVE = 128; /* Once visible to a client, this entity will remain visible. This can be useful for csqc and corpses. While this flag is set, no CSQC_Remove events will be sent for the entity, but this does NOT mean that it will still receive further updates while outside of the pvs. */ -const string INFOKEY_P_IP = "ip"; /* The apparent ip address of the client. This may be a proxy's ip address. */ -const string INFOKEY_P_REALIP = "realip"; /* If sv_getrealip is set, this gives the ip as determine using that algorithm. */ -const string INFOKEY_P_CSQCACTIVE = "csqcactive"; /* Client has csqc enabled. CSQC ents etc will be sent to this player. */ -const string INFOKEY_P_SVPING = "svping"; -const string INFOKEY_P_GUID = "guid"; /* Some hash string which should be reasonably unique to this player's quake installation. */ -const string INFOKEY_P_CHALLENGE = "challenge"; -const string INFOKEY_P_USERID = "*userid"; -const string INFOKEY_P_DOWNLOADPCT = "download"; /* The client's download percentage for the current file. Additional files are not known. */ -const string INFOKEY_P_TRUSTLEVEL = "trustlevel"; -const string INFOKEY_P_PROTOCOL = "protocol"; /* The network protocol the client is using to connect to the server. */ -const string INFOKEY_P_VIP = "*VIP"; /* 1 if the player has the VIP 'penalty'. */ -const string INFOKEY_P_ISMUTED = "*ismuted"; /* 1 if the player has the 'mute' penalty and is not allowed to use the say/say_team commands. */ -const string INFOKEY_P_ISDEAF = "*isdeaf"; /* 1 if the player has the 'deaf' penalty and cannot see other people's say/say_team commands. */ -const string INFOKEY_P_ISCRIPPLED = "*ismuted"; /* 1 if the player has the cripple penalty, and their movement values are ignored (.movement is locked to 0). */ -const string INFOKEY_P_ISCUFFED = "*ismuted"; /* 1 if the player has the cuff penalty, and is unable to attack or use impulses(.button0 and .impulse fields are locked to 0). */ -const string INFOKEY_P_ISLAGGED = "*ismuted"; /* 1 if the player has the fakelag penalty and has an extra 200ms of lag. */ -#endif -#if defined(CSQC) || defined(SSQC) -const string INFOKEY_P_PING = "ping"; /* The player's ping time, in milliseconds. */ -const string INFOKEY_P_NAME = "name"; /* The player's name. */ -const string INFOKEY_P_SPECTATOR = "*spectator"; /* Whether the player is a spectator or not. */ -const string INFOKEY_P_TOPCOLOR = "topcolor"; /* The player's upper/shirt colour (palette index). */ -const string INFOKEY_P_BOTTOMCOLOR = "bottomcolor"; /* The player's lower/pants/trouser colour (palette index). */ -#endif -#ifdef CSQC -const string INFOKEY_P_TOPCOLOR_RGB = "topcolor_rgb"; /* The player's upper/shirt colour as an rgb value in a format usable with stov. */ -const string INFOKEY_P_BOTTOMCOLOR_RGB = "bottomcolor_rgb"; /* The player's lower/pants/trouser colour as an rgb value in a format usable with stov. */ -const string INFOKEY_P_MUTED = "ignored"; /* 0: we can see the result of the player's say/say_team commands. 1: we see no say/say_team messages from this player. Use the ignore command to toggle this value. */ -const string INFOKEY_P_VOIP_MUTED = "vignored"; /* 0: we can hear this player when they speak (assuming voip is generally enabled). 1: we ignore everything this player says. Use cl_voip_mute to change the values. */ -const string INFOKEY_P_ENTERTIME = "entertime"; /* Reads the timestamp at which the player entered the game, in terms of csqc's time global. */ -const string INFOKEY_P_FRAGS = "frags"; /* Reads a player's frag count. */ -const string INFOKEY_P_PACKETLOSS = "pl"; /* Reads a player's packetloss, as a percentage. */ -const string INFOKEY_P_VOIPSPEAKING = "voipspeaking"; /* Boolean value that says whether the given player is currently sending voice information. */ -const string INFOKEY_P_VOIPLOUDNESS = "voiploudness"; /* Only valid for the local player. Gives a value between 0 and 1 to indicate to the user how loud their mic is. */ -const string SERVERKEY_IP = "ip"; /* The address of the server we connected to. */ -const string SERVERKEY_SERVERNAME = "servername"; /* The hostname that was last passed to the connect command. */ -const string SERVERKEY_CONSTATE = "constate"; /* The current connection state. Will be set to one of: disconnected (menu-only mode), active (gamestate received and loaded), connecting(connecting, downloading, or precaching content, aka: loading screen). */ -const string SERVERKEY_TRANSFERRING = "transferring"; /* Set to the hostname of the server that we are attempting to connect or transfer to. */ -const string SERVERKEY_LOADSTATE = "loadstate"; /* loadstage, loading image name, current step, max steps -Stages are: 1=connecting, 2=serverside, 3=clientside -Key will be empty if we are not loading. */ -const string SERVERKEY_PAUSESTATE = "pausestate"; /* 1 if the server claimed to be paused. 0 otherwise */ -const string SERVERKEY_DLSTATE = "dlstate"; /* The progress of any current downloads. Empty string if no download is active, otherwise a tokenizable string containing this info: -files-remaining, total-size, unknown-sizes-flag, file-localname, file-remotename, file-percent, file-rate, file-received-bytes, file-total-bytes -If the current file info is omitted, then we are waiting for a download to start. */ -const string SERVERKEY_PROTOCOL = "protocol"; /* The protocol we are connected to the server with. */ -const string SERVERKEY_MAXPLAYERS = "maxplayers"; /* The number of player/spectator slots allocated on the server. */ -#endif -#ifdef SSQC -const float STUFFCMD_IGNOREINDEMO = 1; /* This stuffcmd will NOT be written to mvds/qtv. */ -const float STUFFCMD_DEMOONLY = 2; /* This stuffcmd will ONLY be written into mvds/qtv streams. */ -const float STUFFCMD_BROADCAST = 4; /* The stuffcmd will be broadcast server-wide (according to the mvd filters). */ -const float STUFFCMD_UNRELIABLE = 8; /* The stuffcmd might not arrive. It might also get there faster than ones sent over the reliable channel. */ -#endif -#if defined(CSQC) || defined(SSQC) -const float FL_FLY = 1; -const float FL_SWIM = 2; -const float FL_CLIENT = 8; -const float FL_INWATER = 16; -const float FL_MONSTER = 32; -#endif -#ifdef SSQC -const float FL_GODMODE = 64; -const float FL_NOTARGET = 128; -#endif -#if defined(CSQC) || defined(SSQC) -const float FL_ITEM = 256; -const float FL_ONGROUND = 512; -const float FL_PARTIALGROUND = 1024; -const float FL_WATERJUMP = 2048; -#endif -#if defined(NQSSQC) -const float FL_JUMPRELEASED = 4096; -#endif -#if defined(CSQC) || defined(SSQC) -const float FL_FINDABLE_NONSOLID = 16384; /* Allows this entity to be found with findradius */ -#endif -#ifdef SSQC -const float FL_LAGGEDMOVE = 65536; /* Enables anti-lag on rockets etc. */ -#endif -#if defined(CSQC) || defined(SSQC) -const float MOVE_NORMAL = 0; -const float MOVE_NOMONSTERS = 1; /* The trace will ignore all non-solid_bsp entities. */ -const float MOVE_MISSILE = 2; /* The trace will use a bbox size of +/- 15 against entities with FL_MONSTER set. */ -const float MOVE_WORLDONLY = 3; /* The trace will ignore everything but the worldmodel. This is useful for to prevent the q3bsp pvs+culling issues that come with spectator modes leaving the world . */ -const float MOVE_HITMODEL = 4; /* Traces will impact the actual mesh of the model instead of merely their bounding box. Should generally only be used for tracelines. Note that this flag is unreliable as an object can animate through projectiles. The bounding box MUST be set to completely encompass the entity or those extra areas will be non-solid (leaving a hole for things to go through). */ -const float MOVE_TRIGGERS = 16; /* This trace type will impact only triggers. It will ignore non-solid entities. */ -const float MOVE_EVERYTHING = 32; /* This type of trace will hit solids and triggers alike. Even non-solid entities. */ -#endif -#ifdef SSQC -const float MOVE_LAGGED = 64; /* Will use antilag based upon the player's latency. Traces will be performed against old positions for entities instead of their current origin. */ -#endif -#if defined(CSQC) || defined(SSQC) -const float MOVE_ENTCHAIN = 128; /* Returns a list of entities impacted via the trace_ent.chain field */ -const float MOVE_OTHERONLY = 256; /* Traces that use this trace type will collide against *only* the entity specified via the 'other' global, and will ignore all owner/solid_not/dimension etc rules, they will still adhere to contents and bsp/bbox rules though. */ -#endif -const float CVAR_TYPEFLAG_EXISTS = 1; /* Cvar name actually exists. */ -const float CVAR_TYPEFLAG_SAVED = 2; /* Cvar is flaged for archival (might need cfg_save to actually save). */ -const float CVAR_TYPEFLAG_PRIVATE = 4; /* QC is not allowed to read. */ -const float CVAR_TYPEFLAG_ENGINE = 8; /* Cvar was created by the engine itself (not user/mod created). */ -const float CVAR_TYPEFLAG_HASDESCRIPTION = 16; /* cvar_description will return something (hopefully) useful. */ -const float CVAR_TYPEFLAG_READONLY = 32; /* cvar may not be changed by qc. */ -const float RESTYPE_MODEL = 0; /* RESTYPE_* constants are used as arguments with the resourcestatus builtin. */ -const float RESTYPE_SOUND = 1; /* precache_sound */ -const float RESTYPE_PARTICLE = 2; /* particleeffectnum */ -#if defined(CSQC) || defined(MENU) -const float RESTYPE_PIC = 3; /* precache_pic. Status results are an amalgomation of the textures used by the named shader. */ -const float RESTYPE_SKIN = 4; /* setcustomskin */ -const float RESTYPE_TEXTURE = 5; /* Individual textures within shaders. These are not directly usable, but may be named as part of a skin file, or a shader. */ -#endif -const float RESSTATE_NOTKNOWN = 0; /* RESSTATE_* constants are return values from the resourcestatus builtin. The engine doesn't know about the resource if it is in this state. This means you will need to precache it. Attempting to use it anyway may result in warnings, errors, or silently succeed, depending on engine version and resource type. */ -const float RESSTATE_NOTLOADED = 1; /* The resource was precached, but has been flushed and there has not been an attempt to reload it. If you use the resource normally, chances are it'll be loaded but at the cost of a stall. */ -const float RESSTATE_LOADING = 2; /* Resources in this this state are queued for loading, and will be loaded at the engine's convienience. If you attempt to query the resource now, the engine will stall until the result is available. sounds in this state may be delayed, while models/pics/shaders may be invisible. */ -const float RESSTATE_FAILED = 3; /* Resources in this state are unusable/could not be loaded. You will get placeholders or dummy results. Queries will not stall the engine. The engine may display placeholder content. */ -const float RESSTATE_LOADED = 4; /* Resources in this state are finally usable, everything will work okay. Hurrah. Queries will not stall the engine. */ -#if defined(CSQC) || defined(SSQC) -const float EF_BRIGHTFIELD = 1; -#endif -#if defined(CSQC) || defined(NQSSQC) -const float EF_MUZZLEFLASH = 2; -#endif -#if defined(CSQC) || defined(SSQC) -const float EF_BRIGHTLIGHT = 4; -const float EF_DIMLIGHT = 8; -#endif -#if defined(QWSSQC) -const float EF_FLAG1 = 16; -const float EF_FLAG2 = 32; -#endif -#if defined(CSQC) || defined(NQSSQC) -const float EF_NODRAW = 16; /* Disables drawing of the model. Does NOT work on QW players. */ -#endif -#if defined(CSQC) || defined(SSQC) -const float EF_ADDITIVE = 32; /* The entity will be drawn with an additive blend. This is NOT supported on players in any quakeworld engine. */ -const float EF_BLUE = 64; /* A blue glow */ -const float EF_RED = 128; /* A red glow */ -const float EF_GREEN = 262144; /* A green glow */ -const float EF_FULLBRIGHT = 512; /* This entity will ignore lighting */ -const float EF_NOSHADOW = 4096; /* This entity will not cast shadows */ -const float EF_NODEPTHTEST = 8192; /* This entity will be drawn over the top of other things that are closer. */ -#endif -#ifdef SSQC -const float EF_NOMODELFLAGS = 8388608; /* Surpresses the normal flags specified in the model. */ -#endif -#if defined(CSQC) || defined(SSQC) -const float MF_ROCKET = 1; -const float MF_GRENADE = 2; -const float MF_GIB = 4; /* Regular blood trail */ -const float MF_ROTATE = 8; -const float MF_TRACER = 16; /* AKA: green scrag trail */ -const float MF_ZOMGIB = 32; /* Dark blood trail */ -const float MF_TRACER2 = 64; /* AKA: hellknight projectile trail */ -const float MF_TRACER3 = 128; /* AKA: purple vore trail */ -#endif -#ifdef SSQC -DEP_CSQC const float SL_ORG_TL = 20; /* Used with showpic etc, specifies that the x+y values are relative to the top-left of the screen */ -DEP_CSQC const float SL_ORG_TR = 21; -DEP_CSQC const float SL_ORG_BL = 22; -DEP_CSQC const float SL_ORG_BR = 23; -DEP_CSQC const float SL_ORG_MM = 24; -DEP_CSQC const float SL_ORG_TM = 25; -DEP_CSQC const float SL_ORG_BM = 26; -DEP_CSQC const float SL_ORG_ML = 27; -DEP_CSQC const float SL_ORG_MR = 28; -#endif -#if defined(CSQC) || defined(SSQC) -const float PFLAGS_NOSHADOW = 1; /* Associated RT lights attached will not cast shadows, making them significantly faster to draw. */ -const float PFLAGS_CORONA = 2; /* Enables support of coronas on the associated rtlights. */ -#endif -#ifdef SSQC -const float PFLAGS_FULLDYNAMIC = 128; /* When set in self.pflags, enables fully-customised dynamic lights. Custom rtlight information is not otherwise used. */ -#endif -const float EV_STRING = 1; -const float EV_FLOAT = 2; -const float EV_VECTOR = 3; -const float EV_ENTITY = 4; -const float EV_FIELD = 5; -const float EV_FUNCTION = 6; -const float EV_POINTER = 7; -const float EV_INTEGER = 8; -const float EV_UINT = 9; -const float EV_INT64 = 10; -const float EV_UINT64 = 11; -const float EV_DOUBLE = 12; -hashtable gamestate; /* Special hash table index for hash_add and hash_get. Entries in this table will persist over map changes (and doesn't need to be created/deleted). */ -const float HASH_REPLACE = 256; /* Used with hash_add. Attempts to remove the old value instead of adding two values for a single key. */ -const float HASH_ADD = 512; /* Used with hash_add. The new entry will be inserted in addition to the existing entry. */ -#ifdef CSQC -const float STAT_HEALTH = 0; /* Player's health. */ -const float STAT_WEAPONMODELI = 2; /* This is the modelindex of the current viewmodel (renamed from the original name 'STAT_WEAPON' due to confusions). */ -const float STAT_AMMO = 3; /* player.currentammo */ -const float STAT_ARMOR = 4; -const float STAT_WEAPONFRAME = 5; -const float STAT_SHELLS = 6; -const float STAT_NAILS = 7; -const float STAT_ROCKETS = 8; -const float STAT_CELLS = 9; -const float STAT_ACTIVEWEAPON = 10; /* player.weapon */ -const float STAT_TOTALSECRETS = 11; -const float STAT_TOTALMONSTERS = 12; -const float STAT_FOUNDSECRETS = 13; -const float STAT_KILLEDMONSTERS = 14; -const float STAT_ITEMS = 15; /* self.items | (self.items2<<23). In order to decode this stat properly, you need to use getstatbits(STAT_ITEMS,0,23) to read self.items, and getstatbits(STAT_ITEMS,23,11) to read self.items2 or getstatbits(STAT_ITEMS,28,4) to read the visible part of serverflags, whichever is applicable. */ -const float STAT_VIEWHEIGHT = 16; /* player.view_ofs_z */ -const float STAT_VIEW2 = 20; /* This stat contains the number of the entity in the server's .view2 field. */ -const float STAT_VIEWZOOM = 21; /* Scales fov and sensitiity. Part of DP_VIEWZOOM. */ -#endif -#if defined(CSQC) || defined(SSQC) -const float STAT_USER = 32; /* Custom user stats start here (lower values are reserved for engine use). */ -#endif -#if defined(CSQC) || defined(MENU) -const float PRECACHE_PIC_FROMWAD = 1; /* Attempt to load it from the legacy gfx.wad file (usually its better to just use a gfx/ prefix instead). */ -const float PRECACHE_PIC_NOCLAMP = 4; /* Texture coords for the pic will not be clamped nor padded nor atlased. */ -const float PRECACHE_PIC_DOWNLOAD = 256; /* If no image could be loaded then attempt to download one from the server. This flag can cause the function to block until completion. (Slow!) */ -const float PRECACHE_PIC_TEST = 512; /* The precache will block until the image is fully loaded, returning a null string on failure. (Slow!) */ -const float VF_MIN = 1; /* The top-left of the 3d viewport in screenspace. The VF_ values are used via the setviewprop/getviewprop builtins. */ -const float VF_MIN_X = 2; -const float VF_MIN_Y = 3; -const float VF_SIZE = 4; /* The width+height of the 3d viewport in screenspace. */ -const float VF_SIZE_X = 5; -const float VF_SIZE_Y = 6; -const float VF_VIEWPORT = 7; /* vector+vector. Two argument shortcut for VF_MIN and VF_SIZE */ -const float VF_FOV = 8; /* sets both fovx and fovy. consider using afov instead. */ -const float VF_FOV_X = 9; /* horizontal field of view. does not consider aspect at all. */ -const float VF_FOV_Y = 10; /* vertical field of view. does not consider aspect at all. */ -const float VF_ORIGIN = 11; /* The origin of the view. Not of the player. */ -const float VF_ORIGIN_X = 12; -const float VF_ORIGIN_Y = 13; -const float VF_ORIGIN_Z = 14; -const float VF_ANGLES = 15; /* The angles the view will be drawn at. Not the angle the client reports to the server. */ -const float VF_ANGLES_X = 16; -const float VF_ANGLES_Y = 17; -const float VF_ANGLES_Z = 18; -#endif -#ifdef CSQC -const float VF_DRAWWORLD = 19; /* boolean. If set to 1, the engine will draw the world and static/persistant rtlights. If 0, the world will be skipped and everything will be fullbright. */ -const float VF_DRAWENGINESBAR = 20; /* boolean. If set to 1, the sbar will be drawn, and viewsize will be honoured automatically. */ -const float VF_DRAWCROSSHAIR = 21; /* boolean. If set to 1, the engine will draw its default crosshair. */ -#endif -#if defined(CSQC) || defined(MENU) -const float VF_MINDIST = 23; /* The distance of the near clip plane from the view position. Should generally not be <=0, as this would introduce NANs. */ -const float VF_MAXDIST = 24; /* The distance of the far clip plane from the view position. If 0, will be considered infinite. */ -#endif -#ifdef CSQC -const float VF_CL_VIEWANGLES = 33; -const float VF_CL_VIEWANGLES_X = 34; -const float VF_CL_VIEWANGLES_Y = 35; -const float VF_CL_VIEWANGLES_Z = 36; -#endif -#if defined(CSQC) || defined(MENU) -const float VF_PERSPECTIVE = 200; /* 1: regular rendering. Fov specifies the angle. 0: isometric-style. Fov specifies the number of Quake Units each side of the viewport, and mindist restrictions are removed, pvs culling should be disabled. */ -#endif -#ifdef CSQC -#define VF_LPLAYER VF_ACTIVESEAT -const float VF_ACTIVESEAT = 202; /* The 'seat' number, used when running splitscreen. */ -#endif -#if defined(CSQC) || defined(MENU) -const float VF_AFOV = 203; /* Aproximate fov. Matches the 'fov' cvar. The engine handles the aspect ratio for you. */ -const float VF_SCREENVSIZE = 204; /* Provides a reliable way to retrieve the current virtual screen size (even if the screen is automatically scaled to retain aspect). */ -const float VF_SCREENPSIZE = 205; /* Provides a reliable way to retrieve the current physical screen size (cvars need vid_restart for them to take effect). */ -#endif -#ifdef CSQC -const float VF_VIEWENTITY = 206; /* Changes the RF_EXTERNALMODEL flag on entities to match the new selection, and removes entities flaged with RF_VIEWENTITY. Requires cunning use of .entnum and typically requires calling addentities(MASK_VIEWMODEL) too. */ -#endif -#if defined(CSQC) || defined(MENU) -const float VF_RT_DESTCOLOUR = 212; /* The texture name to write colour info into, this includes both 3d and 2d drawing. -Additional arguments are: format (IMGFMT_*), sizexy. -Written to by both 3d and 2d rendering. -Note that any rendertarget textures may be destroyed on video mode changes or so. Shaders can name render targets by prefixing texture names with '$rt:', or $sourcecolour. */ -const float VF_RT_DESTCOLOUR1 = 213; /* Like VF_RT_DESTCOLOUR, for multiple render targets. */ -const float VF_RT_DESTCOLOUR2 = 214; /* Like VF_RT_DESTCOLOUR, for multiple render targets. */ -const float VF_RT_DESTCOLOUR3 = 215; /* Like VF_RT_DESTCOLOUR, for multiple render targets. */ -const float VF_RT_SOURCECOLOUR = 209; /* The texture name to use with shaders that specify a $sourcecolour map. */ -const float VF_RT_DEPTH = 210; /* The texture name to use as a depth buffer. Also used for shaders that specify $sourcedepth. 1-based. Additional arguments are: format (IMGFMT_D*), sizexy. */ -const float VF_RT_RIPPLE = 211; /* The texture name to use as a ripplemap (target for shaders with 'sort ripple'). Also used for shaders that specify $ripplemap. 1-based. Additional arguments are: format, sizexy. */ -const float VF_ENVMAP = 220; /* The cubemap name to use as a fallback for $reflectcube, if a shader was unable to load one. Note that this doesn't automatically change shader permutations or anything. */ -const float VF_USERDATA = 221; /* Pointer (and byte size) to an array of vec4s. This data is then globally visible to all glsl via the w_user uniform. */ -#endif -#ifdef CSQC -const float VF_SKYROOM_CAMERA = 222; /* Controls the camera position of the skyroom (which will be drawn underneath transparent sky surfaces). This should move slightly with the real camera, but not so much that the skycamera enters walls. Requires a skyshader with a blend mode on the first pass (or no passes). */ -#endif -#if defined(CSQC) || defined(MENU) -const float VF_PROJECTIONOFFSET = 224; /* vec2 horizontal+vertical offset for the projection matrix, for weird off-centre rendering. */ -const float DRAWFLAG_NORMAL = 0; /* Args for drawpic/drawfill/beginpolygon. Not to be confused with the hexen2-compatibility feature. */ -const float DRAWFLAG_ADD = 1; /* Forces additive blending, overriding any shader settings. */ -const float DRAWFLAG_MODULATE = 2; /* Forces alpha blending, overriding any shader settings. */ -const float DRAWFLAG_2D = 4; /* For use with beginpolygon. The polygon will be drawn to the 2d screen, instead of being added to the 3d scene. */ -const float DRAWFLAG_TWOSIDED = 1024; /* For use with beginpolygon. The polygon will be two-sided without any backface culling. */ -const float DRAWFLAG_LINES = 2048; /* For use with beginpolygon. The surface verticies should be interpreted as a line loop, instead of a triangle fan. */ -const float IMGFMT_R8G8B8A8 = 1; /* Typical 32bit rgba pixel format. */ -const float IMGFMT_R16G16B16A16F = 2; /* Half-Float pixel format. Requires gl3 support. */ -const float IMGFMT_R32G32B32A32F = 3; /* Regular Float pixel format. Requires gl3 support. */ -const float IMGFMT_D16 = 4; /* 16-bit depth pixel format. Must not be used with VF_RT_DESTCOLOUR*. */ -const float IMGFMT_D24 = 5; /* 24-bit depth pixel format. Must not be used with VF_RT_DESTCOLOUR*. */ -const float IMGFMT_D32 = 6; /* 32-bit depth pixel format. Must not be used with VF_RT_DESTCOLOUR*. */ -const float IMGFMT_R8 = 7; /* Single channel red-only 8bit pixel format. */ -const float IMGFMT_R16F = 8; /* Single channel red-only Half-Float pixel format. Requires gl3 support. */ -const float IMGFMT_R32F = 9; /* Single channel red-only Float pixel format. Requires gl3 support. */ -const float IMGFMT_A2B10G10R10 = 10; /* Packed 32-bit packed 10-bit colour pixel format. Requires gl3 support. */ -const float IMGFMT_R5G6B5 = 11; /* Packed 16-bit colour pixel format. */ -const float IMGFMT_R4G4B4A4 = 12; /* Packed 16-bit colour pixel format, with alpha */ -const float IMGFMT_R8G8 = 13; /* 16-bit two-channel pixel format. */ -const float IMGFMT_R32G32B32F = 14; /* A pixel format that matches QC's vector type. */ -#endif -#ifdef CSQC -const float RF_VIEWMODEL = 1; /* Specifies that the entity is a view model, and that its origin is relative to the current view position. These entities are also subject to viewweapon bob. */ -const float RF_EXTERNALMODEL = 2; /* Specifies that this entity should be displayed in mirrors (and may still cast shadows), but will not otherwise be visible. */ -#endif -#if defined(CSQC) || defined(MENU) -const float RF_DEPTHHACK = 4; /* Hacks the depth values such that the entity uses depth values as if it were closer to the screen. This is useful when combined with viewmodels to avoid weapons poking in to walls. */ -const float RF_ADDITIVE = 8; /* Shaders from this entity will temporarily be hacked to use an additive blend mode instead of their normal blend mode. */ -#endif -#ifdef CSQC -const float RF_USEAXIS = 16; /* The entity will be oriented according to the current v_forward+v_right+v_up vector values instead of the entity's .angles field. */ -const float RF_NOSHADOW = 32; /* This entity will not cast shadows. Often useful on view models. */ -const float RF_FRAMETIMESARESTARTTIMES = 64; /* Specifies that the frame1time, frame2time field are timestamps (denoting the start of the animation) rather than time into the animation. */ -const float RF_FIRSTPERSON = 1024; /* This is basically the opposite of RF_EXTERNALMODEL. Don't draw in third-person or mirrors. */ -#endif -#if defined(CSQC) || defined(MENU) -const float IE_KEYDOWN = 0; /* Specifies that a key was pressed. Second argument is the scan code. Third argument is the unicode (printable) char value. Fourth argument denotes which keyboard(or mouse, if its a mouse 'scan' key) the event came from. Note that some systems may completely separate scan codes and unicode values, with a 0 value for the unspecified argument. */ -const float IE_KEYUP = 1; /* Specifies that a key was released. Arguments are the same as IE_KEYDOWN. On some systems, this may be fired instantly after IE_KEYDOWN was fired. */ -const float IE_MOUSEDELTA = 2; /* Specifies that a mouse was moved (touch screens and tablets typically give IE_MOUSEABS events instead, use in_windowed_mouse 0 to test code to cope with either). Second argument is the X displacement, third argument is the Y displacement. Fourth argument is which mouse or touch event triggered the event. */ -const float IE_MOUSEABS = 3; /* Specifies that a mouse cursor or touch event was moved to a specific location relative to the virtual screen space. Second argument is the new X position, third argument is the new Y position. Fourth argument is which mouse or touch event triggered the event. */ -const float IE_ACCELEROMETER = 4; -const float IE_FOCUS = 5; /* Specifies that input focus was given. parama says mouse focus, paramb says keyboard focus. If either are -1, then it is unchanged. */ -const float IE_JOYAXIS = 6; /* Specifies that what value a joystick/controller axis currently specifies. x=axis, y=value. Will be called multiple times, once for each axis of each active controller. */ -const float IE_GYROSCOPE = 7; -const float GGDI_GAMEDIR = 0; /* Used with getgamedirinfo to query the mod's public gamedir. There is often other info that cannot be expressed with just a gamedir name, resulting in dupes or other weirdness. */ -const float GGDI_DESCRIPTION = 1; /* The human-readable title of the mod. Empty when no data is known (ie: the gamedir just contains some maps). */ -const float GGDI_OVERRIDES = 2; /* A list of settings overrides. */ -const float GGDI_LOADCOMMAND = 3; /* The console command needed to actually load the mod. */ -const float GGDI_ICON = 4; /* The mod's Icon path, ready for drawpic. */ -const float GGDI_GAMEDIRLIST = 5; /* A semi-colon delimited list of gamedirs that the mod's content can be loaded through. */ -#endif -#ifdef SSQC -const float CLIENTTYPE_DISCONNECTED = 0; /* Return value from clienttype() builtin. This entity is a player slot that is currently empty. */ -const float CLIENTTYPE_REAL = 1; /* This is a real player, and not a bot. */ -const float CLIENTTYPE_BOT = 2; /* This player slot does not correlate to a real player, any messages sent to this client will be ignored. */ -const float CLIENTTYPE_NOTACLIENT = 3; /* This entity is not even a player slot. This is typically an error condition. */ -#endif -const float FILE_READ = 0; /* The file may be read via fgets to read a single line at a time. */ -const float FILE_APPEND = 1; /* Like FILE_WRITE, but writing starts at the end of the file. */ -const float FILE_WRITE = 2; /* fputs will be used to write to the file. */ -const float FILE_READNL = 4; /* Like FILE_READ, except newlines are not special. fgets reads the entire file into a tempstring. */ -const float FILE_MMAP_READ = 5; /* The file will be loaded into memory. fgets returns a pointer to the first byte (and will always return the same value for this file). Cast this to your datatype. */ -const float FILE_MMAP_RW = 6; /* Like FILE_MMAP_READ, except any changes to the data will be written back to disk once the file is closed. */ -#ifdef CSQC -const float MASK_ENGINE = 1; /* Valid as an argument for addentities. If specified, all non-csqc entities will be added to the scene. */ -const float MASK_VIEWMODEL = 2; /* Valid as an argument for addentities. If specified, the regular engine viewmodel will be added to the scene. */ -const float PREDRAW_AUTOADD = 0; /* Valid as a return value from the predraw function. Returning this will cause the engine to automatically invoke addentity(self) for you. */ -const float PREDRAW_NEXT = 1; /* Valid as a return value from the predraw function. Returning this will simply move on to the next entity without the autoadd behaviour, so can be used for particle/invisible/special entites, or entities that were explicitly drawn with addentity. */ -const float LFIELD_ORIGIN = 0; -const float LFIELD_COLOUR = 1; -const float LFIELD_RADIUS = 2; -const float LFIELD_FLAGS = 3; -const float LFIELD_STYLE = 4; -const float LFIELD_ANGLES = 5; -const float LFIELD_FOV = 6; -const float LFIELD_CORONA = 7; -const float LFIELD_CORONASCALE = 8; -const float LFIELD_CUBEMAPNAME = 9; -const float LFIELD_AMBIENTSCALE = 10; -const float LFIELD_DIFFUSESCALE = 11; -const float LFIELD_SPECULARSCALE = 12; -const float LFIELD_ROTATION = 13; -const float LFIELD_DIETIME = 14; -const float LFIELD_RGBDECAY = 15; -const float LFIELD_RADIUSDECAY = 16; -const float LFIELD_STYLESTRING = 17; -const float LFIELD_NEARCLIP = 18; -const float LFIELD_OWNER = 19; -const float LFLAG_NORMALMODE = 1; -const float LFLAG_REALTIMEMODE = 2; -const float LFLAG_LIGHTMAP = 4; -const float LFLAG_FLASHBLEND = 8; -const float LFLAG_NOSHADOWS = 256; -const float LFLAG_SHADOWMAP = 512; -const float LFLAG_CREPUSCULAR = 1024; -const float LFLAG_ORTHOSUN = 2048; -const float TEREDIT_RELOAD = 0; -const float TEREDIT_SAVE = 1; -const float TEREDIT_SETHOLE = 2; -const float TEREDIT_HEIGHT_SET = 3; -const float TEREDIT_HEIGHT_SMOOTH = 4; -const float TEREDIT_HEIGHT_SPREAD = 5; -const float TEREDIT_HEIGHT_RAISE = 6; -const float TEREDIT_HEIGHT_FLATTEN = 18; -const float TEREDIT_HEIGHT_LOWER = 7; -const float TEREDIT_TEX_KILL = 8; -const float TEREDIT_TEX_GET = 9; -const float TEREDIT_TEX_BLEND = 10; -const float TEREDIT_TEX_UNIFY = 11; -const float TEREDIT_TEX_NOISE = 12; -const float TEREDIT_TEX_BLUR = 13; -const float TEREDIT_TEX_REPLACE = 19; -const float TEREDIT_TEX_SETMASK = 25; -const float TEREDIT_WATER_SET = 14; -const float TEREDIT_MESH_ADD = 15; -const float TEREDIT_MESH_KILL = 16; -const float TEREDIT_TINT = 17; -const float TEREDIT_RESET_SECT = 20; -const float TEREDIT_RELOAD_SECT = 21; -const float TEREDIT_ENT_GET = 26; -const float TEREDIT_ENT_SET = 27; -const float TEREDIT_ENT_ADD = 28; -const float TEREDIT_ENT_COUNT = 29; -#endif -#if defined(CSQC) || defined(MENU) -const float SLIST_HOSTCACHEVIEWCOUNT = 0; -const float SLIST_HOSTCACHETOTALCOUNT = 1; -const float SLIST_MASTERQUERYCOUNT = 2; -const float SLIST_MASTERREPLYCOUNT = 3; -const float SLIST_SERVERQUERYCOUNT = 4; -const float SLIST_SERVERREPLYCOUNT = 5; -const float SLIST_SORTFIELD = 6; -const float SLIST_SORTDESCENDING = 7; -const float SLIST_TEST_CONTAINS = 0; -const float SLIST_TEST_NOTCONTAIN = 1; -const float SLIST_TEST_LESSEQUAL = 2; -const float SLIST_TEST_LESS = 3; -const float SLIST_TEST_EQUAL = 4; -const float SLIST_TEST_GREATER = 5; -const float SLIST_TEST_GREATEREQUAL = 6; -const float SLIST_TEST_NOTEQUAL = 7; -const float SLIST_TEST_STARTSWITH = 8; -const float SLIST_TEST_NOTSTARTSWITH = 9; -#endif -#ifdef MENU -float(string ext) checkextension = #1; /* - Checks if the named extension is supported by the running engine. */ - -void(string err,...) error = #2; /* - Fatal error that will trigger a crash-to-console that users will actually notice. */ - -void(string err,...) objerror = #3; /* - For some reason this has been redefined as non-fatal, and as it won't force the user to look at the console it'll generally be ignored completely so really what's the point? Other than as a convoluted way to remove(self) that is. */ - -void(string text,...) print = #4; /* Part of DP_SV_PRINT - Hello, world. Shoves junk on the console. Hopefully people will bother to read it, maybe. */ - -DEP void(string text,...) bprint = #5; -DEP void(float clientnum, string text,...) msprint = #6; -void(string text,...) cprint = #7; /* - Tries to show the given message in the centre of the screen, assuming that its not obscured by menus. Oh hey look, you're calling it in menuqc! */ - -vector(vector) normalize = #8; -float(vector) vlen = #9; -float(vector) vectoyaw = #10; -vector(vector) vectoangles = #11; -float() random = #12; -void(string,...) localcmd = #13; -float(string name) cvar = #14; -void(string name, string value) cvar_set = #15; -void(string text, ...) dprint = #16; -string(float) ftos = #17; -float(float) fabs = #18; -string(vector) vtos = #19; -string(entity) etos = #20; /* Part of DP_QC_ETOS*/ -float(string) stof = #21; /* Part of FRIK_FILE, FTE_QC_INFOKEY, FTE_STRINGS, QW_ENGINE, ZQ_QC_STRINGS*/ -entity() spawn = #22; -void(entity) remove = #23; -entity(entity start, .string field, string match) find = #24; -entity(entity start, .__variant field, __variant match) findfloat = #25; /* Part of DP_QC_FINDFLOAT*/ -entity(.string field, string match) findchain = #26; /* Part of DP_QC_FINDCHAIN*/ -entity(.__variant field, __variant match) findchainfloat = #27; /* Part of DP_QC_FINDCHAINFLOAT*/ -string(string file) precache_file = #28; /* - Attempts to download the named file from the current server, if it isn't found locally. Not very useful as menuqc is normally meant to work before joining servers too. */ - -string(string sample) precache_sound = #29; -void() coredump = #30; /* - Takes a dump, writing the qcvm's state to disk. There are normally easier ways to debug, but I suppose this one still beats print spam. */ - -void() traceon = #31; /* - Enables single-stepping. Its generally easier to just set a breakpoint. */ - -void() traceoff = #32; /* - Disables single-stepping. Which sucks if you started said singlestepping outside of qc. */ - -void(entity) eprint = #33; -float(float) rint = #34; -float(float) floor = #35; -float(float) ceil = #36; -entity(entity) nextent = #37; -float(float) sin = #38; /* Part of DP_QC_SINCOSSQRTPOW*/ -float(float) cos = #39; /* Part of DP_QC_SINCOSSQRTPOW*/ -float(float) sqrt = #40; /* Part of DP_QC_SINCOSSQRTPOW*/ -vector() randomvector = #41; -float(string name, string value, float flags) registercvar = #42; /* Part of DP_REGISTERCVAR - Creates the cvar if it didn't already exist. This presents issues for setting those cvars via startup configs of course, and autocvars are easier but I suppose they don't get any flags (which are ignored anyway, of course). */ - -float(float,...) min = #43; /* Part of DP_QC_MINMAXBOUND*/ -float(float,...) max = #44; /* Part of DP_QC_MINMAXBOUND*/ -float(float min,float value,float max) bound = #45; /* Part of DP_QC_MINMAXBOUND*/ -float(float,float) pow = #46; /* Part of DP_QC_SINCOSSQRTPOW*/ -void(entity src, entity dst) copyentity = #47; /* Part of DP_QC_COPYENTITY - Copies all entity fields from one entity into another (forgetting any that were previously set on the destination). */ - -filestream(string filename, float mode) fopen = #48; /* Part of FRIK_FILE*/ -void(filestream fhandle) fclose = #49; /* Part of FRIK_FILE*/ -string(filestream fhandle) fgets = #50; /* Part of FRIK_FILE*/ -void(filestream fhandle, string s) fputs = #51; /* Part of FRIK_FILE*/ -float(string) strlen = #52; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ -string(string, optional string, optional string, optional string, optional string, optional string, optional string, optional string) strcat = #53; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ -string(string s, float start, float length) substring = #54; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ -vector(string) stov = #55; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ -FTEDEP("Redundant") string(string) strzone = #56; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS - Exists in FTE for compat only, no different from strcat. */ - -FTEDEP("Redundant") void(string) strunzone = #57; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS - Exists in FTE for compat only, does nothing. */ - -float(string) tokenize = #58; /* Part of KRIMZON_SV_PARSECLIENTCOMMAND - Splits up the given string into its different components (what constitutes a token separator is not well defined and has been hacked about with over the years so have fun with that), returning the number of tokens that were found. Call argv(0 through ret-1) to retrieve each individual token. Take care to not use this recursively. */ - -string(float) argv = #59; /* Part of KRIMZON_SV_PARSECLIENTCOMMAND - Returns one of the tokens found via tokenize (and equivelent builtins). */ - -float() isserver = #60; /* - Returns true if the local engine is running a server, and thus cvars and localcmds are shared with said server. */ - -float() clientcount = #61; /* - Returns the maximum number of players on the server. Useless if its a remote server, so its a kinda useless builtin really. */ - -float() clientstate = #62; /* - Tells you whether the client is actually connected to anything. 0 for a dedicated server (but dedicated servers don't normally run menuqc anyway), 2 if connecting or connected to a server (but not necessarily spawned+active), 1 for sitting around idle without trying to connect to anything yet. */ - -void(string map) changelevel = #64; /* - Not really any different from a localcmd, but with proper string escapes. */ - -void(string sample, optional float channel, optional float volume) localsound = #65; /* - Plays a sound, locally. precaching is optional, but recommended. */ - -vector() getmousepos = #66; /* - Obsolete. Return values depend upon the current cursor mode. Implement Menu_InputEvent instead, so you can handle deltas as-is or absolutes if that's all the OS can provide. */ - -float(optional float timetype) gettime = #67; -void(string s) loadfromdata = #68; /* - Reads a set of entities from the given string. This string should have the same format as a .ent file or a saved game. Entities will be spawned as required. If you need to see the entities that were created, you should use parseentitydata instead. */ - -void(string s) loadfromfile = #69; /* - Reads a set of entities from the named file. This file should have the same format as a .ent file or a saved game. Entities will be spawned as required. If you need to see the entities that were created, you should use parseentitydata instead. */ - -float(float val, float m) mod = #70; -string(string name) cvar_string = #71; /* Part of DP_QC_CVAR_STRING - Returns the value of a cvar, as a string. */ - -FTEDEP("Call 'error' instead") void() crash = #72; /* - Demonstrates that no program is bug free. */ - -void() stackdump = #73; /* - Prints out the QC's stack, for console-based error reports. */ - -searchhandle(string pattern, enumflags:float{SB_CASEINSENSITIVE=1<<0,SB_FULLPACKAGEPATH=1<<1,SB_ALLOWDUPES=1<<2,SB_FORCESEARCH=1<<3,SB_MULTISEARCH=1<<4,SB_NAMESORT=1<<5} flags, float quiet, optional string package) search_begin = #74; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE*/ -void(searchhandle handle) search_end = #75; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE*/ -float(searchhandle handle) search_getsize = #76; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE*/ -string(searchhandle handle, float num) search_getfilename = #77; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE*/ -float(entity) etof = #79; -entity(float) ftoe = #80; -float(string) validstring = #81; /* - Returns true if str isn't null. In case 'if [not](str)' was configured to test for empty instead of null. */ - -DEP float(string str) altstr_count = #82; /* - Reports how many single-quotes there were in the string, divided by 2. */ - -DEP string(string str) altstr_prepare = #83; /* - Adds markup to escape only single-quotes. Does not add any. */ - -DEP string(string str, float num) altstr_get = #84; /* - Gets the Nth single-quoted token in the input. */ - -DEP string(string str, float num, string setval) altstr_set = #85; /* - Changes the Nth single-quoted token. The setval argument must not contain any single-quotes (use altstr_prepare to ensure this). */ - -entity(entity start, .float field, float match) findflags = #87; /* Part of DP_QC_FINDFLAGS*/ -entity(.float field, float match) findchainflags = #88; /* Part of DP_QC_FINDCHAINFLAGS*/ -string(string name) cvar_defstring = #89; /* Part of DP_QC_CVAR_DEFSTRING*/ -void(entity ent, string mname) setmodel = #90; /* - Menuqc-specific version. */ - -void(string mname) precache_model = #91; /* - Menuqc-specific version. */ - -void(entity ent, vector neworg) setorigin = #92; /* - Menuqc-specific version. */ - -#endif -#if defined(CSQC) || defined(SSQC) -void(vector vang) makevectors = #1; /* - Takes an angle vector (pitch,yaw,roll) (+x=DOWN). Writes its results into v_forward, v_right, v_up vectors. */ - -void(entity e, vector o) setorigin = #2; /* - Changes e's origin to be equal to o. Also relinks collision state (as well as setting absmin+absmax), which is required after changing .solid */ - -void(entity e, string m) setmodel = #3; /* - Looks up m in the model precache list, and sets both e.model and e.modelindex to match. BSP models will set e.mins and e.maxs accordingly, other models depend upon the value of sv_gameplayfix_setmodelrealbox - for compatibility you should always call setsize after all pickups or non-bsp models. Also relinks collision state. */ - -void(entity e, vector min, vector max) setsize = #4; /* - Sets the e's mins and maxs fields. Also relinks collision state, which sets absmin and absmax too. */ - -void() breakpoint = #6; /* - Trigger a debugging event. FTE will break into the qc debugger. Other engines may crash with a debug execption. */ - -float() random = #7; /* - Returns a random value between 0 and 1. Be warned, this builtin can return 1 in most engines, which can break arrays. */ - -void(entity e, float chan, string samp, float vol, float atten, optional float speedpct, optional float flags, optional float timeofs) sound = #8; /* - Starts a sound centered upon the given entity. - chan is the entity sound channel to use, channel 0 will allow you to mix many samples at once, others will replace the old sample - 'samp' must have been precached first - if specified, 'speedpct' should normally be around 100 (or =0), 200 for double speed or 50 for half speed. - If flags is specified, the reliable flag in the channels argument is used for additional channels. Flags should be made from SOUNDFLAG_* constants - timeofs should be negative in order to provide a delay before the sound actually starts. */ - -vector(vector v) normalize = #9; /* - Shorten or lengthen a direction vector such that it is only one quake unit long. */ - -void(string e) error = #10; /* - Ends the game with an easily readable error message. */ - -void(string e) objerror = #11; /* - Displays a non-fatal easily readable error message concerning the self entity, including a field dump. self will be removed! */ - -float(vector v) vlen = #12; /* - Returns the square root of the dotproduct of a vector with itself. Or in other words the length of a distance vector, in quake units. */ - -float(vector v, optional entity reference) vectoyaw = #13; /* - Given a direction vector, returns the yaw angle in which that direction vector points. If an entity is passed, the yaw angle will be relative to that entity's gravity direction. */ - -entity() spawn = #14; /* - Adds a brand new entity into the world! Hurrah, you're now a parent! */ - -void(entity e) remove = #15; /* - Destroys the given entity and clears some limited fields (including model, modelindex, solid, classname). Any references to the entity following the call are an error. After half a second the entity will be reused, in the interim you can unfortunatly still read its fields to see if the reference is no longer valid. */ - -#endif -void(entity e) removeinstant = #0:removeinstant; /* - Same thing as the regular remove builtin, but bypasses the half-second rule. The entity slot may be reused instantly. Be CERTAIN that you have no lingering references, because if they're followed they will end up poking an entirely different type of entity! So only use this where you're sure its safe. */ - -#if defined(CSQC) || defined(SSQC) -void(vector v1, vector v2, float flags, entity ent) traceline = #16; /* - Traces a thin line through the world from v1 towards v2. - Will not collide with ent, ent.owner, or any entity who's owner field refers to ent. - The passed entity will also be used to determine whether to use a capsule trace, the contents that the trace should impact, and a couple of other extra fields that define the trace. - There are no side effects beyond the trace_* globals being written. - flags&MOVE_NOMONSTERS will not impact on non-bsp entities. - flags&MOVE_MISSILE will impact with increased size. - flags&MOVE_HITMODEL will impact upon model meshes, instead of their bounding boxes. - flags&MOVE_TRIGGERS will also stop on triggers - flags&MOVE_EVERYTHING will stop if it hits anything, even non-solid entities. - flags&MOVE_LAGGED will backdate entity positions for the purposes of this builtin according to the indicated player ent's latency, to provide lag compensation. */ - -#endif -#ifdef SSQC -entity() checkclient = #17; /* - Returns one of the player entities. The returned player will change periodically. */ - -#endif -#if defined(CSQC) || defined(SSQC) -entity(entity start, .string fld, string match) find = #18; /* - Scan for the next entity with a given field set to the given 'match' value. start should be either world, or the previous entity that was found. Returns world on failure/if there are no more. - If you have many many entities then you may find that hashtables will give more performance (but requires extra upkeep). */ - -#endif -entity*(.__variant fld, __variant match, int type=EV_STRING, __out int count) find_list = #0:find_list; /* - Scan for the next entity with a given field set to the given 'match' value. start should be either world, or the previous entity that was found. Returns world on failure/if there are no more. - If you have many many entities then you may find that hashtables will give more performance (but requires extra upkeep). */ - -#if defined(CSQC) || defined(SSQC) -string(string s) precache_sound = #19; /* - Precaches a sound, making it known to clients and loading it from disk. This builtin (strongly) should be called during spawn functions. This builtin must be called for the sound before the sound builtin is called, or it might not even be heard. */ - -string(string s) precache_model = #20; /* - Precaches a model, making it known to clients and loading it from disk if it has a .bsp extension. This builtin (strongly) should be called during spawn functions. This must be called for each model name before setmodel may use that model name. - Modelindicies precached in SSQC will always be positive. CSQC precaches will be negative if they are not also on the server. */ - -#endif -#ifdef SSQC -void(entity client, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7) stuffcmd = #21; /* - Sends a console command (or cvar) to the client, where it will be executed. Different clients support different commands. Do NOT forget the final \n. - This builtin is generally considered evil. */ - -void(entity client, float flags, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6) stuffcmdflags = #0:stuffcmdflags; /* Part of FTE_QC_STUFFCMDFLAGS - Sends a console command (or cvar) to the client, where it will be executed. Different clients support different commands. Do NOT forget the final \n. - This (just as evil) variant allows specifying some flags too. See the STUFFCMD_* constants. */ - -#endif -#if defined(CSQC) || defined(SSQC) -entity(vector org, float rad, optional .entity chainfield) findradius = #22; /* - Finds all entities within a distance of the 'org' specified. One entity is returned directly, while other entities are returned via that entity's .chain field. Use findradius_list for an updated alternative without reenterancy issues. */ - -entity*(vector org, float rad, __out int foundcount, int sort=0) findradius_list = #0:findradius_list; /* - Finds all entities linked with a bbox within a distance of the 'org' specified, returning the list as a temp-array (world signifies the end). Unlike findradius, sv_gameplayfix_blowupfallenzombies is ignored (use FL_FINDABLE_NONSOLID instead), while sv_gameplayfix_findradiusdistancetobox and dpcompat_findradiusarealinks are force-enabled. The resulting buffer will automatically be cleaned up by the engine and does not need to be freed. */ - -#endif -#if defined(NQSSQC) -void(string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7, optional string s8) bprint = #23; /* - NQ: Concatenates all arguments, and prints the messsage on the console of all connected clients. */ - -#endif -#if defined(QWSSQC) -void(float msglvl, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7) bprint = #23; /* - QW: Concatenates all string arguments, and prints the messsage on the console of only all clients who's 'msg' infokey is set lower or equal to the supplied 'msglvl' argument. */ - -#endif -#if defined(NQSSQC) -void(entity client, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7) sprint = #24; /* - NQ: Concatenates all string arguments, and prints the messsage on the named client's console */ - -#endif -#if defined(QWSSQC) -void(entity client, float msglvl, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6) sprint = #24; /* - QW: Concatenates all string arguments, and prints the messsage on the named client's console, but only if that client's 'msg' infokey is set lower or equal to the supplied 'msglvl' argument. */ - -#endif -#if defined(CSQC) || defined(NQSSQC) -void(string s, ...) dprint = #25; /* - NQ: Prints the given message on the server's console, but only if the developer cvar is set. Arguments will be concatenated into a single message. */ - -#endif -#if defined(CSQC) || defined(QWSSQC) -void(string s, ...) dprint = #25; /* - QW: Unconditionally prints the given message on the server's console. Arguments will be concatenated into a single message. */ - -#endif -#if defined(CSQC) || defined(SSQC) -string(float val) ftos = #26; /* - Returns a tempstring containing a representation of the given float. Precision depends upon engine. */ - -string(vector val) vtos = #27; /* - Returns a tempstring containing a representation of the given vector. Precision depends upon engine. */ - -void() coredump = #28; /* - Writes out a coredump. This contains stack, globals, and field info for all ents. This can be handy for debugging. */ - -void() traceon = #29; /* - Enables tracing. This may be spammy, slow, and stuff. Set debugger 1 in order to use fte's qc debugger. */ - -void() traceoff = #30; /* - Disables tracing again. */ - -void(entity e) eprint = #31; /* - Debugging builtin that prints all fields of the given entity to the console. */ - -float(float yaw, float dist, optional float settraceglobals) walkmove = #32; /* - Attempt to walk the entity at a given angle for a given distance. - if settraceglobals is set, the trace_* globals will be set, showing the results of the movement. - This function will trigger touch events. */ - -float() droptofloor = #34; /* - Instantly moves the entity downwards until it hits the ground. If the entity is in solid or would need to drop more than 'pr_droptofloorunits' quake units, its position will be considered invalid and the builtin will abort, returning FALSE, otherwise TRUE. */ - -void(float lightstyle, string stylestring, optional vector rgb) lightstyle = #35; /* - Specifies an auto-animating string that specifies the light intensity for entities using that lightstyle. - a is off, z is fully lit. Should be lower case only. - rgb will recolour all lights using that lightstyle. */ - -float(float) rint = #36; /* - Rounds the given float up or down to the closest integeral value. X.5 rounds away from 0 */ - -float(float) floor = #37; /* - Rounds the given float downwards, even when negative. */ - -float(float) ceil = #38; /* - Rounds the given float upwards, even when negative. */ - -float(entity ent) checkbottom = #40; /* - Expensive checks to ensure that the entity is actually sitting on something solid, returns true if it is. */ - -float(vector pos) pointcontents = #41; /* - Checks the given point to see what is there. Returns one of the CONTENTS_* constants. Just because a point is empty does not mean that the player can stand there due to the size of the player - use tracebox for such tests. */ - -__uint(vector pos, optional float worldonly=1) pointcontentsmask = #0:pointcontentsmask; /* - Checks the given point to see what is there. Returns a mask of the CONTENTBIT_* constants. Just because a point is empty does not mean that the player can stand there due to the size of the player - use tracebox for such tests. */ - -float(float) fabs = #43; /* - Removes the sign of the float, making it positive if it is negative. */ - -#endif -#ifdef SSQC -vector(entity player, float missilespeed) aim = #44; /* - Returns a tweaked copy of the v_forward vector (must be set! ie: makevectors(player.v_angle) ). This is important for keyboard users (that don't want to have to look up/down the whole time), as well as joystick users (who's aim is otherwise annoyingly imprecise). Only the upwards component of the result will differ from the value of v_forward. The builtin will select the enemy closest to the crosshair within the angle of acos(sv_aim). */ - -#endif -#if defined(CSQC) || defined(SSQC) -float(string) cvar = #45; /* - Returns the numeric value of the named cvar */ - -void(string, ...) localcmd = #46; /* - Adds the string to the console command queue. Commands will not be executed immediately, but rather at the start of the following frame. */ - -entity(entity) nextent = #47; /* - Returns the following entity. Skips over removed entities. Returns world when passed the last valid entity. */ - -void(vector pos, vector dir, float colour, float count) particle = #48; /* - Spawn 'count' particles around 'pos' moving in the direction 'dir', with a palette colour index between 'colour' and 'colour+8'. */ - -#define ChangeYaw changeyaw -void() changeyaw = #49; /* - Changes the self.angles_y field towards self.ideal_yaw by up to self.yaw_speed. */ - -vector(vector fwd, optional vector up) vectoangles = #51; /* - Returns the angles (+x=UP) required to orient an entity to look in the given direction. The 'up' argument is required if you wish to set a roll angle, otherwise it will be limited to just monster-style turning. */ - -#endif -#ifdef SSQC -void(float to, float val) WriteByte = #52; /* - Writes a single byte into a network message buffer. Typically you will find a more correct alternative to writing arbitary data. 'to' should be one of the MSG_* constants. MSG_ONE must have msg_entity set first. */ - -void(float to, float val) WriteChar = #53; /* - Writes a signed value between -128 and 127. */ - -void(float to, float val) WriteShort = #54; /* - Writes a signed value between -32768 and 32767. As an exception, values up to 65535 will not trigger warnings (but readshort will read the result as negative!) */ - -void(float to, float val) WriteLong = #55; /* - Writes a signed 32bit integer. Note that the input argument being of float type limits the resulting integer to a mere 24 consecutive bits of validity. Use WriteInt if you want to write an entire 32bit int without data loss. */ - -void(float to, float val) WriteCoord = #56; /* - Writes a single value suitable for a map coordinate axis. The precision is not strictly specified but is assumed to be of at least 13.3 fixed-point precision (ie: +/-4k with 1/8th precision). */ - -void(float to, float val) WriteAngle = #57; /* - Writes a single value suitable for an angle axis. The precision is not strictly specified but is assumed to be 8bit, giving 256 notches instead of the assumed 360 range passed in. */ - -void(float to, string val) WriteString = #58; /* - Writes a variable-length null terminated string. There are length limits. The codepage is not translated, so be sure that client+server agree on whether utf-8 is being used or not (or just stick to ascii+markup). */ - -void(float to, entity val) WriteEntity = #59; /* - Writes the index of the specified entity (the network data size is not specified). This can be read clientside using the readentitynum builtin, with caveats. */ - -#endif -#if defined(CSQC) || defined(SSQC) -float(float angle) sin = #60; /* Part of DP_QC_SINCOSSQRTPOW - Forgive me father, for I have trigonometry homework. */ - -float(float angle) cos = #61; /* Part of DP_QC_SINCOSSQRTPOW*/ -float(float value) sqrt = #62; /* Part of DP_QC_SINCOSSQRTPOW*/ -#endif -#ifdef SSQC -float(float a, float n) modulo = #0:modulo; -#endif -#if defined(CSQC) || defined(SSQC) -void(entity ent) changepitch = #63; /* Part of DP_QC_CHANGEPITCH*/ -void(entity ent, entity ignore) tracetoss = #64; -string(entity ent) etos = #65; /* Part of DP_QC_ETOS*/ -void(float step) movetogoal = #67; /* - Runs lots and lots of fancy logic in order to try to step the entity the specified distance towards its goalentity. */ - -string(string s) precache_file = #68; /* - This builtin does nothing. It was used only as a hint for pak generation. */ - -void(entity e) makestatic = #69; /* - Sends a copy of the entity's renderable fields to all clients, and REMOVES the entity, preventing further changes. This means it will be unmutable and non-solid. */ - -#endif -#ifdef SSQC -void(string mapname, optional string newmapstartspot) changelevel = #70; /* - Attempts to change the map to the named map. If 'newmapstartspot' is specified, the state of the current map will be preserved, and the argument will be passed to the next map in the 'startspot' global, and the next map will be loaded from archived state if it was previously visited. If not specified, all archived map states will be purged. */ - -#endif -#if defined(CSQC) || defined(SSQC) -void(string cvarname, string valuetoset) cvar_set = #72; /* - Instantly sets a cvar to the given string value. Warning: the resulting string includes apostrophies surrounding the result. You may wish to use sprintf instead. */ - -#endif -#ifdef SSQC -void(entity ent, string text, optional string text2, optional string text3, optional string text4, optional string text5, optional string text6, optional string text7) centerprint = #73; -#endif -#if defined(CSQC) || defined(SSQC) -void (vector pos, string samp, float vol, float atten) ambientsound = #74; -string(string str) precache_model2 = #75; -string(string str) precache_sound2 = #76; -string(string str) precache_file2 = #77; -#endif -#ifdef SSQC -void(entity player) setspawnparms = #78; -float() ex_finaleFinished = #0:ex_finaleFinished; /* - Behaviour is undocumented. */ - -void(entity client, string sample) ex_localsound = #0:ex_localsound; /* - Behaviour is undocumented. */ - -void(entity ent, string text, optional string s0, optional string s1, optional string s2, optional string s3, optional string s4, optional string s5) ex_centerprint = #0:ex_centerprint; /* - Remaster: Sends the strings to the client, which will order according to {#}. Also substitutes localised strings for $NAME strings. */ - -void(string s, optional string s0, optional string s1, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6) ex_bprint = #0:ex_bprint; /* - Remaster: Sends the strings to all clients, which will order them according to {#}. Also substitutes localised strings for $NAME strings. */ - -void(entity client, string s, optional string s0, optional string s1, optional string s2, optional string s3, optional string s4, optional string s5) ex_sprint = #0:ex_sprint; /* - Remaster: Sends the strings to the client, which will order according to {#}. Also substitutes localised strings for $NAME strings. */ - -float(entity playerEnt) ex_CheckPlayerEXFlags = #0:ex_CheckPlayerEXFlags; /* - Behaviour is undocumented. */ - -void(entity killer, entity killee) logfrag = #79; /* Part of QW_ENGINE*/ -#endif -#if defined(CSQC) || defined(SSQC) -string(entity e, string key) infokey = #80; /* Part of FTE_QC_INFOKEY, QW_ENGINE - If e is world, returns the field 'key' from either the serverinfo or the localinfo. If e is a player, returns the value of 'key' from the player's userinfo string. There are a few special exceptions, like 'ip' which is not technically part of the userinfo. */ - -#endif -#ifdef SSQC -float(entity e, string key) infokeyf = #0:infokeyf; /* - Identical to regular infokey, except returns a float. */ - -int(entity e, string key, optional void *outbuf, int outbufsize) infokey_blob = #0:infokey_blob; /* - Retrieves a user's blob size, and optionally writes it to the specified buffer. */ - -#endif -#if defined(CSQC) || defined(SSQC) -float(string) stof = #81; /* Part of FRIK_FILE, FTE_QC_INFOKEY, FTE_STRINGS, QW_ENGINE, ZQ_QC_STRINGS*/ -#endif -#ifdef SSQC -#define unicast(pl,reli) do{msg_entity = pl; multicast('0 0 0', reli?MULITCAST_ONE_R:MULTICAST_ONE);}while(0) -void(vector where, float set) multicast = #82; /* Part of EXT_CSQC, FTE_QC_MULTICAST - Once the MSG_MULTICAST network message buffer has been filled with data, this builtin is used to dispatch it to the given target, filtering by pvs for reduced network bandwidth. */ - -DEP void(entity to, string str) redirectcmd = #101; /* Part of ??MVDSV_BUILTINS - Executes a single console command, and sends the text generated by it to the specified player. The command will be executed at the end of the frame once QC is no longer running - you may wish to pre/postfix it with 'echo'. */ - -#endif -#if defined(CSQC) || defined(SSQC) -string(float style, optional __out vector rgb) getlightstyle = #0:getlightstyle; /* - Obtains the light style string for the given style. */ - -vector(float style) getlightstylergb = #0:getlightstylergb; /* - Obtains the current rgb value of the specified light style. In csqc, this is correct with regard to the current frame, while ssqc gives no guarentees about time and ignores client cvars. Note: use getlight if you want the actual light value at a point. */ - -#endif -#ifdef SSQC -void(float style, float val, optional vector rgb) lightstylestatic = #5; /* - Sets the lightstyle to an explicit numerical level. From Hexen2. */ - -#endif -#if defined(CSQC) || defined(SSQC) -void(vector start, vector mins, vector maxs, vector end, float nomonsters, entity ent) tracebox = #90; /* Part of DP_QC_TRACEBOX - Exactly like traceline, but a box instead of a uselessly thin point. Acceptable sizes are limited by bsp format, q1bsp has strict acceptable size values. */ - -vector() randomvec = #91; /* Part of DP_QC_RANDOMVEC - Returns a vector with random values. Each axis is independantly a value between -1 and 1 inclusive. */ - -vector(vector org) getlight = #92; /* Part of DP_QC_GETLIGHT*/ -float(string cvarname, string defaultvalue) registercvar = #93; /* Part of DP_REGISTERCVAR - Creates a new cvar on the fly. If it does not already exist, it will be given the specified value. If it does exist, this is a no-op. - This builtin has the limitation that it does not apply to configs or commandlines. Such configs will need to use the set or seta command causing this builtin to be a noop. - In engines that support it, you will generally find the autocvar feature easier and more efficient to use. */ - -float(float a, float b, ...) min = #94; /* Part of DP_QC_MINMAXBOUND - Returns the lowest value of its arguments. */ - -float(float a, float b, ...) max = #95; /* Part of DP_QC_MINMAXBOUND - Returns the highest value of its arguments. */ - -float(float minimum, float val, float maximum) bound = #96; /* Part of DP_QC_MINMAXBOUND - Returns val, unless minimum is higher, or maximum is less. */ - -float(float value, float exp) pow = #97; /* Part of DP_QC_SINCOSSQRTPOW*/ -#endif -float(float v, optional float base) logarithm = #0:logarithm; /* - Determines the logarithm of the input value according to the specified base. This can be used to calculate how much something was shifted by. */ - -#if defined(CSQC) || defined(SSQC) -#define findentity findfloat -entity(entity start, .__variant fld, __variant match) findfloat = #98; /* Part of DP_QC_FINDFLOAT - Equivelent to the find builtin, but instead of comparing strings contents, this builtin compares the raw values. This builtin requires multiple calls in order to scan all entities - set start to the previous call's return value. - world is returned when there are no more entities. */ - -float(string extname) checkextension = #99; /* - Checks for an extension by its name (eg: checkextension("FRIK_FILE") says that its okay to go ahead and use strcat). - Use cvar("pr_checkextension") to see if this builtin exists. */ - -#endif -float(__variant funcref) checkbuiltin = #0:checkbuiltin; /* - Checks to see if the specified builtin is supported/mapped. This is intended as a way to check for #0 functions, allowing for simple single-builtin functions. Warning, if two different engines map different builtins to the same number, then this function will not tell you which will be called, only that it won't crash (the exception being #0, which are remapped as available). */ - -#ifdef SSQC -float(string builtinname) builtin_find = #100; /* - Looks to see if the named builtin is valid, and returns the builtin number it exists at. */ - -#endif -#if defined(CSQC) || defined(SSQC) -float(float value) anglemod = #102; -float(float newangle, float oldangle) anglesub = #0:anglesub; /* - Returns newangle-oldangle, except returning the shortest route around a circle so yields a result between -180 and +180. */ - -#endif -#ifdef SSQC -DEP_CSQC void(string slot, string picname, float x, float y, float zone, optional entity player) showpic = #104; /* Part of TEI_SHOWLMP2*/ -DEP_CSQC void(string slot, optional entity player) hidepic = #105; /* Part of TEI_SHOWLMP2*/ -DEP_CSQC void(string slot, float x, float y, float zone, optional entity player) movepic = #106; /* Part of TEI_SHOWLMP2*/ -DEP_CSQC void(string slot, string picname, optional entity player) changepic = #107; /* Part of TEI_SHOWLMP2*/ -#endif -#if defined(CSQC) || defined(SSQC) -filestream(string filename, float mode, optional float mmapminsize) fopen = #110; /* Part of FRIK_FILE - Opens a file, typically prefixed with "data/", for either read or write access. */ - -void(filestream fhandle) fclose = #111; /* Part of FRIK_FILE*/ -string(filestream fhandle) fgets = #112; /* Part of FRIK_FILE - Reads a single line out of the file. The new line character is not returned as part of the string. Returns the null string on EOF (use if not(string) to easily test for this, which distinguishes it from the empty string which is returned if the line being read is blank */ - -void(filestream fhandle, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7) fputs = #113; /* Part of FRIK_FILE - Writes the given string(s) into the file. For compatibility with fgets, you should ensure that the string is terminated with a \n - this will not otherwise be done for you. It is up to the engine whether dos or unix line endings are actually written. */ - -#endif -int(filestream fhandle, void *ptr, int size) fread = #0:fread; /* Part of FTE_QC_FILE_BINARY - Reads binary data out of the file. Returns truncated lengths if the read exceeds the length of the file. */ - -int(filestream fhandle, void *ptr, int size) fwrite = #0:fwrite; /* Part of FTE_QC_FILE_BINARY - Writes binary data out of the file. */ - -#define ftell fseek //c compat -int(filestream fhandle, optional int newoffset) fseek = #0:fseek; /* Part of FTE_QC_FILE_BINARY - Changes the current position of the file, if specified. Returns prior position, in bytes. */ - -int(filestream fhandle, optional int newsize) fsize = #0:fsize; /* Part of FTE_QC_FILE_BINARY - Reports the total size of the file, in bytes. Can also be used to truncate/extend the file */ - -#if defined(CSQC) || defined(SSQC) -float(string s) strlen = #114; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ -string(string s1, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7, optional string s8) strcat = #115; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ -string(string s, float start, float length) substring = #116; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ -vector(string s) stov = #117; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ -FTEDEP("Redundant") string(string s, ...) strzone = #118; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS - Create a semi-permanent copy of a string that only becomes invalid once strunzone is called on the string (instead of when the engine assumes your string has left scope). This builtin has become redundant in FTEQW due to the FTE_QC_PERSISTENTTEMPSTRINGS extension and is now functionally identical to strcat for compatibility with old engines+mods. */ - -FTEDEP("Redundant") void(string s) strunzone = #119; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS - Destroys a string that was allocated by strunzone. Further references to the string MAY crash the game. In FTE, this function became redundant and now does nothing. */ - -#endif -void*(int bytes) createbuffer = #0:createbuffer; /* - Returns a temporary buffer that can be written to / read from. The buffer will be garbage collected and thus cannot be explicitly freed. Tempstrings and buffer references must not be stored into the buffer as the garbage collector will not scan these. */ - -#ifdef SSQC -void(string cvar, float val) cvar_setf = #176; -#endif -#if defined(CSQC) || defined(SSQC) -void(string soundname, optional float channel, optional float volume) localsound = #177; /* - Plays a sound... locally... probably best not to call this from ssqc. Also disables reverb. */ - -float(string modelname, optional float queryonly) getmodelindex = #200; /* - Acts as an alternative to precache_model(foo);setmodel(bar, foo); return bar.modelindex; - If queryonly is set and the model was not previously precached, the builtin will return 0 without needlessly precaching the model. */ - -float(string soundname, optional float queryonly) getsoundindex = #0:getsoundindex; /* - Provides a way to query if a sound is already precached or not. The return value can also be checked for <=255 to see if it'll work over any network protocol. The sound index can also be used for writebyte hacks, but this is discouraged - use SOUNDFLAG_UNICAST instead. */ - -__variant(float prnum, string funcname, ...) externcall = #201; /* Part of FTE_MULTIPROGS - Directly call a function in a different/same progs by its name. - prnum=0 is the 'default' or 'main' progs. - prnum=-1 means current progs. - prnum=-2 will scan through the active progs and will use the first it finds. */ - -float(string progsname) addprogs = #202; /* Part of FTE_MULTIPROGS - Loads an additional .dat file into the current qcvm. The returned handle can be used with any of the externcall/externset/externvalue builtins. - There are cvars that allow progs to be loaded automatically. */ - -__variant(float prnum, string varname) externvalue = #203; /* Part of FTE_MULTIPROGS - Reads a global in the named progs by the name of that global. - prnum=0 is the 'default' or 'main' progs. - prnum=-1 means current progs. - prnum=-2 will scan through the active progs and will use the first it finds. */ - -void(float prnum, __variant newval, string varname) externset = #204; /* Part of FTE_MULTIPROGS - Sets a global in the named progs by name. - prnum=0 is the 'default' or 'main' progs. - prnum=-1 means current progs. - prnum=-2 will scan through the active progs and will use the first it finds. */ - -void(entity portal, float state) openportal = #207; /* - Opens or closes the portals associated with a door or some such on q2 or q3 maps. On Q2BSPs, the entity should be the 'func_areaportal' entity - its style field will say which portal to open. On Q3BSPs, the entity is the door itself, the portal will be determined by the two areas found from a preceding setorigin call. */ - -#endif -#ifdef SSQC -float(float attributes, string effectname, ...) RegisterTempEnt = #208; /* Part of FTE_PEXT_CUSTOMTENTS*/ -void(float type, vector pos, ...) CustomTempEnt = #209; /* Part of FTE_PEXT_CUSTOMTENTS*/ -float(optional float sleeptime) fork = #210; /* Part of FTE_MULTITHREADED - When called, this builtin simply returns. Twice. - The current 'thread' will return instantly with a return value of 0. The new 'thread' will return after sleeptime seconds with a return value of 1. See documentation for the 'sleep' builtin for limitations/requirements concerning the new thread. Note that QC should probably call abort in the new thread, as otherwise the function will return to the calling qc function twice also. */ - -#endif -void(optional __variant ret) abort = #211; /* Part of FTE_MULTITHREADED - QC execution is aborted. Parent QC functions on the stack will be skipped, effectively this forces all QC functions to 'return ret' until execution returns to the engine. If ret is ommited, it is assumed to be 0. */ - -#ifdef SSQC -void(float sleeptime) sleep = #212; /* Part of FTE_MULTITHREADED - Suspends the current QC execution thread for 'sleeptime' seconds. - Other QC functions can and will be executed in the interim, including changing globals and field state (but not simultaneously). - The self and other globals will be restored when the thread wakes up (or set to world if they were removed since the thread started sleeping). Locals will be preserved, but will not be protected from remove calls. - If the engine is expecting the QC to return a value (even in the parent/root function), the value 0 shall be used instead of waiting for the qc to resume. */ - -void(entity player, string key, string value) forceinfokey = #213; /* Part of FTE_FORCEINFOKEY - Directly changes a user's info without pinging off the client. Also allows explicitly setting * keys, including *spectator. Does not affect the user's config or other servers. */ - -void(entity player, string key, void *data, int size) forceinfokeyblob = #0:forceinfokeyblob; /* Part of FTE_INFOBLOBS - Directly changes a user's info without pinging off the client. Also allows explicitly setting * keys, including *spectator. Does not affect the user's config or other servers. */ - -#endif -#if defined(CSQC) || defined(SSQC) -void(vector org, vector dmin, vector dmax, float colour, float effect, float count) particle2 = #215; /* Part of FTE_HEXEN2*/ -void(vector org, vector box, float colour, float effect, float count) particle3 = #216; /* Part of FTE_HEXEN2*/ -void(vector org, float radius, float colour, float effect, float count) particle4 = #217; /* Part of FTE_HEXEN2*/ -float(float number, float quantity) bitshift = #218; /* Part of EXT_BITSHIFT*/ -void(vector pos) te_lightningblood = #219; /* Part of FTE_TE_STANDARDEFFECTBUILTINS*/ -#endif -float(string s1, string sub, optional float startidx) strstrofs = #221; /* Part of FTE_STRINGS - Returns the 0-based offset of sub within the s1 string, or -1 if sub is not in s1. - If startidx is set, this builtin will ignore matches before that 0-based offset. */ - -float(string str, float index) str2chr = #222; /* Part of FTE_STRINGS - Retrieves the character value at offset 'index'. */ - -string(float chr, ...) chr2str = #223; /* Part of FTE_STRINGS - The input floats are considered character values, and are concatenated. */ - -string(float ccase, float redalpha, float redchars, string str, ...) strconv = #224; /* Part of FTE_STRINGS - Converts quake chars in the input string amongst different representations. - ccase specifies the new case for letters. - 0: not changed. - 1: forced to lower case. - 2: forced to upper case. - redalpha and redchars switch between colour ranges. - 0: no change. - 1: Forced white. - 2: Forced red. - 3: Forced gold(low) (numbers only). - 4: Forced gold (high) (numbers only). - 5+6: Forced to white and red alternately. - You should not use this builtin in combination with UTF-8. */ - -string(float pad, string str1, ...) strpad = #225; /* Part of FTE_STRINGS - Pads the string with spaces, to ensure its a specific length (so long as a fixed-width font is used, anyway). If pad is negative, the spaces are added on the left. If positive the padding is on the right. */ - -infostring(infostring old, string key, string value) infoadd = #226; /* Part of FTE_STRINGS - Returns a new tempstring infostring with the named value changed (or added if it was previously unspecified). Key and value may not contain the \ character. */ - -string(infostring info, string key) infoget = #227; /* Part of FTE_STRINGS - Reads a named value from an infostring. The returned value is a tempstring */ - -#define strcmp strncmp -float(string s1, string s2, optional float len, optional float s1ofs, optional float s2ofs) strncmp = #228; /* Part of FTE_STRINGS - Compares up to 'len' chars in the two strings. s1ofs allows you to treat s2 as a substring to compare against, or should be 0. - Returns 0 if the two strings are equal, a negative value if s1 appears numerically lower, and positive if s1 appears numerically higher. */ - -float(string s1, string s2) strcasecmp = #229; /* Part of FTE_STRINGS - Compares the two strings without case sensitivity. - Returns 0 if they are equal. The sign of the return value may be significant, but should not be depended upon. */ - -float(string s1, string s2, float len, optional float s1ofs, optional float s2ofs) strncasecmp = #230; /* Part of FTE_STRINGS - Compares up to 'len' chars in the two strings without case sensitivity. s1ofs allows you to treat s2 as a substring to compare against, or should be 0. - Returns 0 if they are equal. The sign of the return value may be significant, but should not be depended upon. */ - -string(string s) strtrim = #0:strtrim; /* - Trims the whitespace from the start+end of the string. */ - -#if defined(CSQC) || defined(SSQC) -__deprecated("Use strftime.") void() calltimeofday = #231; /* Part of FTE_CALLTIMEOFDAY - Asks the engine to instantly call the qc's 'timeofday' function, before returning. For compatibility with mvdsv. - timeofday should have the prototype: void(float secs, float mins, float hour, float day, float mon, float year, string strvalue) - The strftime builtin is more versatile and less weird. */ - -#endif -#ifdef SSQC -void(float num, float type, .__variant fld) clientstat = #232; /* Part of EXT_CSQC - Specifies what data to use in order to send various stats, in a client-specific way. - 'num' should be a value between 32 and 127, other values are reserved. - 'type' must be set to one of the EV_* constants, one of EV_FLOAT, EV_STRING, EV_INTEGER, EV_ENTITY. - fld must be a reference to the field used, each player will be sent only their own copy of these fields. */ - -void(float num, float type, string name) globalstat = #233; /* - Specifies what data to use in order to send various stats, in a non-client-specific way. num and type are as in clientstat, name however, is the name of the global to read in the form of a string (pass "foo"). */ - -void(float num, float type, __variant *address) pointerstat = #0:pointerstat; /* - Specifies what data to use in order to send various stats, in a non-client-specific way. num and type are as in clientstat, address however, is the address of the variable you would like to use (pass &foo). */ - -void(entity ent, vector sendflags, entity unicastplayer) setsendneeded = #0:setsendneeded; /* - Flags the entity as needing to be resent. This builtin allows for more bits than supported by the SendEntity field, as well as allows flagging sends to specific players. */ - -float(entity player) isbackbuffered = #234; /* Part of FTE_ISBACKBUFFERED - Returns if the given player's network buffer will take multiple network frames in order to clear. If this builtin returns non-zero, you should delay or reduce the amount of reliable (and also unreliable) data that you are sending to that client. */ - -#endif -#if defined(CSQC) || defined(SSQC) -void(vector angle) rotatevectorsbyangle = #235; /* - rotates the v_forward,v_right,v_up matrix by the specified angles. */ - -void(vector fwd, vector right, vector up) rotatevectorsbyvectors = #236; -float(float mdlindex, string skinname) skinforname = #237; -#endif -#if defined(CSQC) || defined(MENU) -float(string shadername, optional string defaultshader, ...) shaderforname = #238; /* Part of FTE_FORCESHADER - Caches the named shader and returns a handle to it. - If the shader could not be loaded from disk (missing file or ruleset_allow_shaders 0), it will be created from the 'defaultshader' string if specified, or a 'skin shader' default will be used. - defaultshader if not empty should include the outer {} that you would ordinarily find in a shader. */ - -#endif -#ifdef CSQC -void(string shadername, string replacement, float timeoffset) remapshader = #0:remapshader; /* - All surfaces drawn with the specified shader will instead be drawn using the specified replacement shader. Shaders can be remapped to something else later by using the same source shadername. This is mostly useful for worldmodel surfaces (eg showing which team is currently winning). Entities should generally use setcustomskin or forceshader instead. Remaps will be forgotten on vid_reload, but can be reapplied via CSQC_RendererRestarted. */ - -#endif -#if defined(CSQC) || defined(SSQC) -void(vector org, optional float count) te_bloodqw = #239; /* Part of FTE_TE_STANDARDEFFECTBUILTINS*/ -#endif -#ifdef SSQC -void(entity ent) te_muzzleflash = #0:te_muzzleflash; -#endif -#if defined(CSQC) || defined(SSQC) -float(vector viewpos, entity entity) checkpvs = #240; /* Part of FTE_QC_CHECKPVS*/ -#endif -#ifdef SSQC -entity(string match, optional float matchnum) matchclientname = #241; /* Part of FTE_QC_MATCHCLIENTNAME*/ -#endif -float(string destaddress, string content) sendpacket = #242; /* Part of FTE_QC_SENDPACKET - Sends a UDP packet to the specified destination. Note that the payload will be prefixed with four 255 bytes as a sort of security feature. */ - -#ifdef CSQC -vector(entity ent, float tagnum) rotatevectorsbytag = #244; -#endif -#if defined(CSQC) || defined(SSQC) -float(float dividend, float divisor) mod = #245; -#endif -#ifdef SSQC -float(optional string host, optional string user, optional string pass, optional string defaultdb, optional string driver) sqlconnect = #250; /* Part of FTE_SQL*/ -void(float serveridx) sqldisconnect = #251; /* Part of FTE_SQL*/ -float(float serveridx, void(float serveridx, float queryidx, float rows, float columns, float eof, float firstrow) callback, float querytype, string query) sqlopenquery = #252; /* Part of FTE_SQL*/ -void(float serveridx, float queryidx) sqlclosequery = #253; /* Part of FTE_SQL*/ -string(float serveridx, float queryidx, float row, float column) sqlreadfield = #254; /* Part of FTE_SQL*/ -string(float serveridx, optional float queryidx) sqlerror = #255; /* Part of FTE_SQL*/ -string(float serveridx, string data) sqlescape = #256; /* Part of FTE_SQL*/ -string(float serveridx) sqlversion = #257; /* Part of FTE_SQL*/ -float(float serveridx, float queryidx, float row, float column) sqlreadfloat = #258; /* Part of FTE_SQL*/ -int(float serveridx, float queryidx, float row, float column, __variant *ptr, int maxsize) sqlreadblob = #0:sqlreadblob; -string(float serveridx, __variant *ptr, int maxsize) sqlescapeblob = #0:sqlescapeblob; -#endif -typedef struct json_s *json_t; -accessor jsonnode : json_t; -jsonnode(string) json_parse = #0:json_parse; /* - Parses the given JSON string. */ - -void(jsonnode) json_free = #0:json_free; /* - Frees a json tree and all of its children. Must only be called on the root node. */ - -enum json_type_e : int -{ - JSON_TYPE_STRING, - JSON_TYPE_NUMBER, - JSON_TYPE_OBJECT, - JSON_TYPE_ARRAY, - JSON_TYPE_TRUE, - JSON_TYPE_FALSE, - JSON_TYPE_NULL -}; -json_type_e(jsonnode node) json_get_value_type = #0:json_get_value_type; /* - Get type of a JSON value. */ - -int(jsonnode node) json_get_integer = #0:json_get_integer; /* - Get an integer from a json node. */ - -float(jsonnode node) json_get_float = #0:json_get_float; /* - Get a float from a json node. */ - -string(jsonnode node) json_get_string = #0:json_get_string; /* - Get a string from a value. Returns a null string if its not a string type. */ - -jsonnode(jsonnode node, string) json_find_object_child = #0:json_find_object_child; /* - Find a child of a json object by name. Returns NULL if the handle couldn't be found. */ - -int(jsonnode node) json_get_length = #0:json_get_length; /* - Get the length of a json array or object. Returns 0 if its not an array. */ - -jsonnode(jsonnode node, int childindex) json_get_child_at_index = #0:json_get_child_at_index; /* - Get the nth child of a json array or object. Returns NULL if the index is out of range. */ - -string(jsonnode node) json_get_name = #0:json_get_name; /* - Gets the object's name (useful if you're using json_get_child_at_index to walk an object's children for whatever reason). */ - -string(string javascript) js_run_script = #0:js_run_script; /* - Runs the provided javascript snippet. This builtin functions only in emscripten builds, returning a null string on other systems (or if the script evaluates to null). */ - -#if defined(CSQC) || defined(SSQC) -int(string) stoi = #259; /* Part of FTE_QC_INTCONV - Converts the given string into a true integer. Base 8, 10, or 16 is determined based upon the format of the string. */ - -string(int) itos = #260; /* Part of FTE_QC_INTCONV - Converts the passed true integer into a base10 string. */ - -int(string) stoh = #261; /* Part of FTE_QC_INTCONV - Reads a base-16 string (with or without 0x prefix) as an integer. Bugs out if given a base 8 or base 10 string. :P */ - -string(int) htos = #262; /* Part of FTE_QC_INTCONV - Formats an integer as a base16 string, with leading 0s and no prefix. Always returns 8 characters. */ - -#endif -int(float) ftoi = #0:ftoi; /* Part of FTE_QC_INTCONV - Converts the given float into a true integer without depending on extended qcvm instructions. */ - -float(int, optional float shift, float mask=24) itof = #0:itof; /* Part of FTE_QC_INTCONV - Converts the given true integer into a float without depending on extended qcvm instructions. If shift and mask are specified then only specific parts of the integer will be cast to float. */ - -#if defined(CSQC) || defined(SSQC) -float(float modlindex, optional float useabstransforms) skel_create = #263; /* Part of FTE_CSQC_SKELETONOBJECTS - Allocates a new uninitiaised skeletal object, with enough bone info to animate the given model. - eg: self.skeletonobject = skel_create(self.modelindex); */ - -float(float skel, entity ent, float modelindex, float retainfrac, float firstbone, float lastbone, optional float addfrac) skel_build = #264; /* Part of FTE_CSQC_SKELETONOBJECTS - Animation data (according to the entity's frame info) is pulled from the specified model and blended into the specified skeletal object. - If retainfrac is set to 0 on the first call and 1 on the others, you can blend multiple animations together according to the addfrac value. The final weight should be 1. Other values will result in scaling and/or other weirdness. You can use firstbone and lastbone to update only part of the skeletal object, to allow legs to animate separately from torso, use 0 for both arguments to specify all, as bones are 1-based. */ - -typedef struct -{ - int sourcemodelindex; /*frame data will be imported from this model, bones must be compatible*/ - int reserved; - int firstbone; - int lastbone; - float prescale; /*0 destroys existing data, 1 retains it*/ - float scale[4]; /*you'll need to do lerpfrac manually*/ - int animation[4]; - float animationtime[4]; - /*halflife models*/ - float subblend[2]; - float controllers[5]; -} skelblend_t; -float(float skel, int numblends, skelblend_t *weights, int structsize) skel_build_ptr = #0:skel_build_ptr; /* - Like skel_build, but slightly simpler. */ - -float(float skel) skel_get_numbones = #265; /* Part of FTE_CSQC_SKELETONOBJECTS - Retrives the number of bones in the model. The valid range is 1<=bone<=numbones. */ - -string(float skel, float bonenum) skel_get_bonename = #266; /* Part of FTE_CSQC_SKELETONOBJECTS - Retrieves the name of the specified bone. Mostly only for debugging. */ - -float(float skel, float bonenum) skel_get_boneparent = #267; /* Part of FTE_CSQC_SKELETONOBJECTS - Retrieves which bone this bone's position is relative to. Bone 0 refers to the entity's position rather than an actual bone */ - -float(float skel, string tagname) skel_find_bone = #268; /* Part of FTE_CSQC_SKELETONOBJECTS - Finds a bone by its name, from the model that was used to create the skeletal object. */ - -vector(float skel, float bonenum) skel_get_bonerel = #269; /* Part of FTE_CSQC_SKELETONOBJECTS - Gets the bone position and orientation relative to the bone's parent. Return value is the offset, and v_forward, v_right, v_up contain the orientation. */ - -vector(float skel, float bonenum) skel_get_boneabs = #270; /* Part of FTE_CSQC_SKELETONOBJECTS - Gets the bone position and orientation relative to the entity. Return value is the offset, and v_forward, v_right, v_up contain the orientation. - Use gettaginfo for world coord+orientation. */ - -void(float skel, float bonenum, vector org, optional vector fwd, optional vector right, optional vector up) skel_set_bone = #271; /* Part of FTE_CSQC_SKELETONOBJECTS - Sets a bone position relative to its parent. If the orientation arguments are not specified, v_forward+v_right+v_up are used instead. */ - -void(float skel, float bonenum, vector org, optional vector fwd, optional vector right, optional vector up) skel_premul_bone = #272; /* Part of FTE_CSQC_SKELETONOBJECTS - Transforms a single bone by a matrix. You can use makevectors to generate a rotation matrix from an angle. */ - -void(float skel, float startbone, float endbone, vector org, optional vector fwd, optional vector right, optional vector up) skel_premul_bones = #273; /* Part of FTE_CSQC_SKELETONOBJECTS - Transforms an entire consecutive range of bones by a matrix. You can use makevectors to generate a rotation matrix from an angle, but you'll probably want to divide the angle by the number of bones. */ - -void(float skel, float bonenum, vector org, optional vector fwd, optional vector right, optional vector up) skel_postmul_bone = #0:skel_postmul_bone; /* - Transforms a single bone by a matrix. You can use makevectors to generate a rotation matrix from an angle. */ - -void(float skeldst, float skelsrc, float startbone, float entbone) skel_copybones = #274; /* Part of FTE_CSQC_SKELETONOBJECTS - Copy bone data from one skeleton directly into another. */ - -void(float skel) skel_delete = #275; /* Part of FTE_CSQC_SKELETONOBJECTS - Deletes a skeletal object. The actual delete is delayed, allowing the skeletal object to be deleted in an entity's predraw function yet still be valid by the time the addentity+renderscene builtins need it. Also uninstanciates any ragdoll currently in effect on the skeletal object. */ - -float(float modidx, string framename) frameforname = #276; /* Part of FTE_CSQC_SKELETONOBJECTS - Looks up a framegroup from a model by name, avoiding the need for hardcoding. Returns -1 on error. */ - -float(float modidx, float framenum) frameduration = #277; /* Part of FTE_CSQC_SKELETONOBJECTS - Retrieves the duration (in seconds) of the specified framegroup. */ - -float(float modidx, int actionid) frameforaction = #0:frameforaction; /* - Returns a random frame/animation for the specified mod-defined action, or -1 if no animations have the specified action. */ - -void(float modidx, float framenum, __inout float basetime, float targettime, void(float timestamp, int code, string data) callback) processmodelevents = #0:processmodelevents; /* Part of FTE_GFX_MODELEVENTS - Calls a callback for each event that has been reached. Basetime is set to targettime. */ - -float(float modidx, float framenum, __inout float basetime, float targettime, __out int code, __out string data) getnextmodelevent = #0:getnextmodelevent; /* Part of FTE_GFX_MODELEVENTS - Reports the next event within a model's animation. Returns a boolean if an event was found between basetime and targettime. Writes to basetime,code,data arguments (if an event was found, basetime is set to the event's time, otherwise to targettime). - WARNING: this builtin cannot deal with multiple events with the same timestamp (only the first will be reported). */ - -float(float modidx, float framenum, int eventidx, __out float timestamp, __out int code, __out string data) getmodeleventidx = #0:getmodeleventidx; /* Part of FTE_GFX_MODELEVENTS - Reports an indexed event within a model's animation. Writes to timestamp,code,data arguments on success. Returns false if the animation/event/model was out of range/invalid. Does not consider looping animations (retry from index 0 if it fails and you know that its a looping animation). This builtin is more annoying to use than getnextmodelevent, but can be made to deal with multiple events with the exact same timestamp. */ - -#endif -#define dotproduct(v1,v2) ((vector)(v1)*(vector)(v2)) -vector(vector v1, vector v2) crossproduct = #0:crossproduct; /* Part of FTE_QC_CROSSPRODUCT - Small helper function to calculate the crossproduct of two vectors. */ - -#if defined(CSQC) || defined(SSQC) -float(entity pusher, vector move, vector amove) pushmove = #0:pushmove; -__variant(float action, optional vector pos, optional float radius, optional float quant, ...) terrain_edit = #278; /* Part of FTE_TERRAIN_MAP - Realtime terrain editing. Actions are the TEREDIT_ constants. */ - -typedef struct -{ - string shadername; - vector planenormal; - float planedist; - vector sdir; - float sbias; - vector tdir; - float tbias; -} brushface_t; -int(float modelidx, int brushid, brushface_t *out_faces, int maxfaces, int *out_contents) brush_get = #0:brush_get; /* Part of FTE_RAW_MAP - Queries a brush's information. You must pre-allocate the face array for the builtin to write to. Return value is the number of faces retrieved, 0 on error. */ - -int(float modelidx, brushface_t *in_faces, int numfaces, int contents, optional int brushid) brush_create = #0:brush_create; /* Part of FTE_RAW_MAP - Inserts a new brush into the model. Return value is the new brush's id. */ - -void(float modelidx, int brushid) brush_delete = #0:brush_delete; /* Part of FTE_RAW_MAP - Destroys the specified brush. */ - -float(float modelid, int brushid, int faceid, float selectedstate) brush_selected = #0:brush_selected; /* Part of FTE_RAW_MAP - Allows you to easily set transient visual properties of a brush. returns old value. selectedstate=-1 changes nothing (called for its return value). */ - -int(float modelid, int brushid, int faceid, vector *points, int maxpoints) brush_getfacepoints = #0:brush_getfacepoints; /* Part of FTE_RAW_MAP - Returns the list of verticies surrounding the given face. If face is 0, returns the center of the brush (if space for 1 point) or the mins+maxs (if space for 2 points). */ - -int(int faceid, brushface_t *in_faces, int numfaces, vector *points, int maxpoints) brush_calcfacepoints = #0:brush_calcfacepoints; /* Part of FTE_RAW_MAP - Determines the points of the specified face, if the specified brush were to actually be created. */ - -int(float modelid, vector *planes, float *dists, int numplanes, int *out_brushes, int *out_faces, int maxresults) brush_findinvolume = #0:brush_findinvolume; /* Part of FTE_RAW_MAP - Allows you to easily obtain a list of brushes+faces within the given bounding region. If out_faces is not null, the same brush might be listed twice. */ - -typedef struct -{ - string shadername; - int contents; - int cpwidth; - int cpheight; - int tesswidth; - int tessheight; - vector texinfo;/*scalex,y,rot*/ -} patchinfo_t; -typedef struct -{ - vector xyz; - vector rgb; float a; - float s, t; -} patchvert_t; -#define patch_delete(modelidx,patchidx) brush_delete(modelidx,patchidx) -int(float modelidx, int patchid, patchvert_t *out_controlverts, int maxcp, patchinfo_t *out_info) patch_getcp = #0:patch_getcp; /* - Queries a patch's information. You must pre-allocate the face array for the builtin to write to. Return value is the total number of control verts that were retrieved, 0 on error. */ - -int(float modelidx, int patchid, patchvert_t *out_verts, int maxverts, __out patchinfo_t out_info) patch_getmesh = #0:patch_getmesh; /* - Queries a patch's information. You must pre-allocate the face array for the builtin to write to. Return value is the total number of control verts that were retrieved, 0 on error. */ - -int(float modelidx, int oldpatchid, patchvert_t *in_controlverts, patchinfo_t in_info) patch_create = #0:patch_create; /* - Inserts a new patch into the model. Return value is the new patch's id. */ - -typedef struct -{ - vector dest; - int linkflags; - float radius; -} nodeslist_t; -void(entity ent, vector dest, int denylinkflags, void(entity ent, vector dest, int numnodes, nodeslist_t *nodelist) callback) route_calculate = #0:route_calculate; /* - Begin calculating a route. The callback function will be called once the route has finished being calculated. The route must be memfreed once it is no longer needed. The route must be followed in reverse order (ie: the first node that must be reached is at index numnodes-1). If no route is available then the callback will be called with no nodes. */ - -void(optional entity ent, optional vector neworigin) touchtriggers = #279; /* - Triggers a touch events between self and every SOLID_TRIGGER entity that it is in contact with. This should typically just be the triggers touch functions. Also optionally updates the origin of the moved entity. */ - -#endif -#ifdef SSQC -void(float buf, float fl) WriteFloat = #280; /* - Writes a full 32bit float without any data conversions at all, for full precision. */ - -void(float buf, __double dbl) WriteDouble = #0:WriteDouble; /* - Writes a full 64bit double-precision float without any data conversions at all, for excessive precision. */ - -void(float buf, int fl) WriteInt = #0:WriteInt; /* - Writes all 4 bytes of a 32bit integer without truncating to a float first before converting back to an int (unlike WriteLong does, but otherwise equivelent). */ - -void(float buf, __int64 fl) WriteInt64 = #0:WriteInt64; /* - Writes all 8 bytes of a 64bit integer. This uses variable-length coding and will send only a single byte for any value between -64 and 63. */ - -void(float buf, __uint64 fl) WriteUInt64 = #0:WriteUInt64; /* - Writes all 8 bytes of a 64bit unsigned integer. Values between 0-127 will be sent in a single byte. */ - -#endif -#if defined(CSQC) || defined(SSQC) -float(entity skelent, string dollcmd, float animskel) skel_ragupdate = #281; /* Part of FTE_QC_RAGDOLL_WIP - Updates the skeletal object attached to the entity according to its origin and other properties. - if animskel is non-zero, the ragdoll will animate towards the bone state in the animskel skeletal object, otherwise they will pick up the model's base pose which may not give nice results. - If dollcmd is not set, the ragdoll will update (this should be done each frame). - If the doll is updated without having a valid doll, the model's default .doll will be instanciated. - commands: - doll foo.doll : sets up the entity to use the named doll file - dollstring TEXT : uses the doll file directly embedded within qc, with that extra prefix. - cleardoll : uninstanciates the doll without destroying the skeletal object. - animate 0.5 : specifies the strength of the ragdoll as a whole - animatebody somebody 0.5 : specifies the strength of the ragdoll on a specific body (0 will disable ragdoll animations on that body). - enablejoint somejoint 1 : enables (or disables) a joint. Disabling joints will allow the doll to shatter. */ - -float*(float skel) skel_mmap = #282; /* Part of FTE_QC_RAGDOLL_WIP - Map the bones in VM memory. They can then be accessed via pointers. Each bone is 12 floats, the four vectors interleaved (sadly). */ - -void(entity ent, float bonenum, vector org, optional vector angorfwd, optional vector right, optional vector up) skel_set_bone_world = #283; /* Part of FTE_QC_RAGDOLL_WIP - Sets the world position of a bone within the given entity's attached skeletal object. The world position is dependant upon the owning entity's position. If no orientation argument is specified, v_forward+v_right+v_up are used for the orientation instead. If 1 is specified, it is understood as angles. If 3 are specified, they are the forawrd/right/up vectors to use. */ - -string(float modidx, float framenum) frametoname = #284; -string(float modidx, float skin) skintoname = #285; -float(float resourcetype, float tryload, string resourcename) resourcestatus = #286; /* - resourcetype must be one of the RESTYPE_ constants. Returns one of the RESSTATE_ constants. Tryload 0 is a query only. Tryload 1 will attempt to reload the content if it was flushed. */ - -#endif -hashtable(float tabsize, optional float defaulttype) hash_createtab = #287; /* Part of FTE_QC_HASHTABLES - Creates a hash table object. - The tabsize argument is a performance hint and should generally be set to something similar to the number of entries expected, typically a power of two assumption. Too high simply wastes memory, too low results in extra string compares but no actual bugs. - defaulttype must be one of the EV_* values, if specified. - The hash table with index 0 is a game-persistant table and will NEVER be returned by this builtin (except as an error return). */ - -void(hashtable table) hash_destroytab = #288; /* Part of FTE_QC_HASHTABLES - Destroys a hash table object. */ - -void(hashtable table, string name, __variant value, optional float typeandflags) hash_add = #289; /* Part of FTE_QC_HASHTABLES - Adds the given key with the given value to the table. - If flags&HASH_REPLACE, the old value will be removed, otherwise if flags&HASH_ADD then a duplicate entry will be added with a second value (can be obtained via hash_get's index argument). - The type argument describes how the value should be stored in saved games, as well as providing constraints with the hash_get function. While you can claim that all variables are just vectors, being more precise can result in less issues with tempstrings or saved games - be sure to be explicit with EV_STRING where appropriate because tempstrings may be reclaimed before the get (especially with saved games or table 0). */ - -__variant(hashtable table, string name, optional __variant deflt, optional float requiretype, optional float index) hash_get = #290; /* Part of FTE_QC_HASHTABLES - Looks up the specified key name in the hash table. Returns deflt if the key was not found. - If requiretype is specified then the function will only consider entries of the matching type (allowing you to store both flags+strings under a single name without getting confused). - If index is specified then the function will ignore the first N entries with the same key (applicable only with entries added using HASH_ADD, not HASH_REPLACE), allowing you to store multiple entries. Keep querying higher indexes starting from 0 until it returns the deflt value. - You will usually need to cast the result of this function to a real datatype. */ - -__variant(hashtable table, string name) hash_delete = #291; /* Part of FTE_QC_HASHTABLES - removes the named key. returns the value of the object that was destroyed, or 0 on error. */ - -string(hashtable table, float idx) hash_getkey = #292; /* Part of FTE_QC_HASHTABLES - gets some random key name. add+delete can change return values of this, so don't blindly increment the key index if you're removing all. */ - -float(string name) checkcommand = #294; /* Part of FTE_QC_CHECKCOMMAND - Checks to see if the supplied name is a valid command, cvar, or alias. Returns 0 if it does not exist. */ - -string(string s) argescape = #295; /* - Marks up a string so that it can be reliably tokenized as a single argument later. */ - -#ifdef SSQC -void(string dest, string from, string cmd, string info) clusterevent = #0:clusterevent; /* - Only functions in mapcluster mode. Sends an event to whichever server the named player is on. The destination server can then dispatch the event to the client or handle it itself via the SV_ParseClusterEvent entrypoint. If dest is empty, the event is broadcast to ALL servers. If the named player can't be found, the event will be returned to this server with the cmd prefixed with 'error:'. */ - -string(entity player, optional string newnode) clustertransfer = #0:clustertransfer; /* - Only functions in mapcluster mode. Initiate transfer of the player to a different node. Can take some time. If dest is specified, returns null on error. Otherwise returns the current/new target node (or null if not transferring). */ - -#endif -#if defined(CSQC) || defined(SSQC) -float(float mdlidx) modelframecount = #0:modelframecount; /* - Retrieves the number of frames in the specified model. */ - -#endif -#if defined(CSQC) || defined(MENU) -void() clearscene = #300; /* - Forgets all rentities, polygons, and temporary dlights. Resets all view properties to their default values. */ - -#endif -#ifdef CSQC -void(float mask) addentities = #301; /* - Walks through all entities effectively doing this: - if (ent.drawmask&mask){ if (!ent.predaw()) addentity(ent); } - If mask&MASK_DELTA, non-csqc entities, particles, and related effects will also be added to the rentity list. - If mask&MASK_STDVIEWMODEL then the default view model will also be added. */ - -#endif -#if defined(CSQC) || defined(MENU) -void(entity ent) addentity = #302; /* - Copies the entity fields into a new rentity for later rendering via addscene. */ - -void(entity ent, vector lightdir, vector lightavg, vector lightrange, int reserved1=0,void*reserved2=0) addentity_lighting = #0:addentity_lighting; /* - Copies the entity fields into a new rentity for later rendering via addscene, but with explicit lighting info. */ - -#endif -#ifdef CSQC -void(entity ent) removeentity = #0:removeentity; /* - Undoes all addentities added to the scene from the given entity, without removing ALL entities (useful for splitscreen/etc, readd modified versions as desired). */ - -typedef float vec2[2]; -typedef float vec3[3]; -typedef float vec4[4]; -typedef struct trisoup_simple_vert_s {vec3 xyz;vec2 st;vec4 rgba;} trisoup_simple_vert_t; -void(string texturename, int flags, struct trisoup_simple_vert_s *verts, int *indexes, int numindexes) addtrisoup_simple = #0:addtrisoup_simple; /* - Adds the specified trisoup into the scene as additional geometry. This permits caching geometry to reduce builtin spam. Indexes are a triangle list (so eg quads will need 6 indicies to form two triangles). NOTE: this is not going to be a speedup over polygons if you're still generating lots of new data every frame. */ - -#endif -#if defined(CSQC) || defined(MENU) -#define setviewprop setproperty -float(float property, ...) setproperty = #303; /* - Allows you to override default view properties like viewport, fov, and whether the engine hud will be drawn. Different VF_ values have slightly different arguments, some are vectors, some floats. */ - -void() renderscene = #304; /* - Draws all entities, polygons, and particles on the rentity list (which were added via addentities or addentity), using the various view properties set via setproperty. There is no ordering dependancy. - The scene must generally be cleared again before more entities are added, as entities will persist even over to the next frame. - You may call this builtin multiple times per frame, but should only be called from CSQC_UpdateView. */ - -#endif -#ifdef CSQC -float(vector org, float radius, vector lightcolours, optional float style, optional string cubemapname, optional float pflags) dynamiclight_add = #305; /* - Adds a temporary dlight, ready to be drawn via addscene. Cubemap orientation will be read from v_forward/v_right/v_up. */ - -#endif -void(string texturename, optional float flags, optional float is2d) R_BeginPolygon = #306; /* - Specifies the shader to use for the following polygons, along with optional flags. - If is2d, the polygon will be drawn as soon as the EndPolygon call is made, rather than waiting for renderscene. This allows complex 2d effects. */ - -void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex = #307; /* - Specifies a polygon vertex with its various properties. */ - -void() R_EndPolygon = #308; /* - Ends the current polygon. At least 3 verticies must have been specified. You do not need to call beginpolygon again if you wish to draw another polygon with the same shader. */ - -#ifdef CSQC -void(float radius, vector texcoordbias) R_EndPolygonRibbon = #0:R_EndPolygonRibbon; /* - Ends the current primitive and duplicates each vertex sideways into a ribbon. The texcoordbias will be added to each duplicated vertex allowing for regular 2d textures. At least 2 verticies must have been specified. You do not need to call beginpolygon again if you wish to draw another polygon with the same shader. */ - -#endif -#if defined(CSQC) || defined(MENU) -#define getviewprop getproperty -__variant(float property) getproperty = #309; /* - Retrieve a currently-set (typically view) property, allowing you to read the current viewport or other things. Due to cheat protection, certain values may be unretrievable. */ - -#endif -#ifdef CSQC -vector (vector v) unproject = #310; /* - Transform a 2d screen-space point (with depth) into a 3d world-space point, according the various origin+angle+fov etc settings set via setproperty. */ - -vector (vector v) project = #311; /* - Transform a 3d world-space point into a 2d screen-space point, according the various origin+angle+fov etc settings set via setproperty. */ - -#endif -#if defined(CSQC) || defined(MENU) -float(vector pos, vector size, float alignflags, string text) drawtextfield = #0:drawtextfield; /* - Draws a multi-line block of text, including word wrapping and alignment. alignflags bits are RTLB, typically 3. Returns the total number of lines. */ - -#endif -#ifdef CSQC -void(float width, vector pos1, vector pos2, vector rgb, float alpha, optional float drawflag) drawline = #315; /* - Draws a 2d line between the two 2d points. */ - -float(string name) iscachedpic = #316; /* - Checks to see if the image is currently loaded. Engines might lie, or cache between maps. */ - -string(string name, optional float flags) precache_pic = #317; /* - Forces the engine to load the named image. Flags are a bitmask of the PRECACHE_PIC_* flags. */ - -#endif -#if defined(CSQC) || defined(MENU) -void(string imagename, int width, int height, void *pixeldata, optional int datasize, optional int format) r_uploadimage = #0:r_uploadimage; /* Part of FTE_CSQC_RAWIMAGES - Updates a texture with the specified rgba data (uploading it to the gpu). Will be created if needed. If datasize is specified then the image is decoded (eg .ktx or .dds data) instead of being raw R8G8B8A data. You'll typically want shaderforname to also generate a shader to use the texture. */ - -int*(string filename, __out int width, __out int height, __out int format) r_readimage = #0:r_readimage; /* Part of FTE_CSQC_RAWIMAGES - Reads and decodes an image from disk, providing raw R8G8B8A8 pixel data. Should not be used for dds or ktx etc formats. Returns __NULL__ if the image could not be read for any reason. Use memfree to free the data once you're done with it. */ - -#endif -#ifdef CSQC -#define draw_getimagesize drawgetimagesize -vector(string picname) drawgetimagesize = #318; /* - Returns the dimensions of the named image. Images specified with .lmp should give the original .lmp's dimensions even if texture replacements use a different resolution. WARNING: this function may be slow if used without or directly after its initial precache_pic. */ - -void(string name) freepic = #319; /* - Tells the engine that the image is no longer needed. The image will appear to be new the next time its needed. */ - -string(string modelname, int frame, float frametime) spriteframe = #0:spriteframe; /* - Obtains a suitable shader name to draw a sprite's shader via drawpic/R_BeginPolygon/etc, instead of needing to create a scene. */ - -float(vector position, float character, vector size='8 8', vector rgb='1 1 1', float alpha=1, optional float drawflag=0) drawcharacter = #320; /* - Draw the given quake character at the given position. - If flag&4, the function will consider the char to be a unicode char instead (or display as a ? if outside the 32-127 range). - size should normally be something like '8 8 0'. - rgb should normally be '1 1 1' - alpha normally 1. - Software engines may assume the named defaults. - Note that ALL text may be rescaled on the X axis due to variable width fonts. The X axis may even be ignored completely. */ - -float(vector position, string text, vector size, vector rgb, float alpha, optional float drawflag) drawrawstring = #321; /* - Draws the specified string without using any markup at all, even in engines that support it. - If UTF-8 is globally enabled in the engine, then that encoding is used (without additional markup), otherwise it is raw quake chars. - Software engines may assume a size of '8 8 0', rgb='1 1 1', alpha=1, flag&3=0, but it is not an error to draw out of the screen. */ - -float(vector position, string pic, vector size, vector rgb='1 1 1', float alpha=1, optional float drawflag=0) drawpic = #322; /* - Draws an shader within the given 2d screen box. Software engines may omit support for rgb+alpha, but must support rescaling, and must clip to the screen without crashing. */ - -float(vector position, vector size, vector rgb, float alpha, optional float drawflag) drawfill = #323; /* - Draws a solid block over the given 2d box, with given colour, alpha, and blend mode (specified via flags). - flags&3=0 simple blend. - flags&3=1 additive blend */ - -void(float x, float y, float width, float height) drawsetcliparea = #324; /* - Specifies a 2d clipping region (aka: scissor test). 2d draw calls will all be clipped to this 2d box, the area outside will not be modified by any 2d draw call (even 2d polygons). */ - -void(void) drawresetcliparea = #325; /* - Reverts the scissor/clip area to the whole screen. */ - -float(vector position, string text, vector size='8 8', vector rgb='1 1 1', float alpha=1, float drawflag=0) drawstring = #326; /* - Draws a string, interpreting markup and recolouring as appropriate. */ - -float(string text, float usecolours, vector fontsize='8 8') stringwidth = #327; /* - Calculates the width of the screen in virtual pixels. If usecolours is 1, markup that does not affect the string width will be ignored. Will always be decoded as UTF-8 if UTF-8 is globally enabled. - If the char size is not specified, '8 8 0' will be assumed. */ - -void(vector pos, vector sz, string pic, vector srcpos, vector srcsz, vector rgb, float alpha, optional float drawflag) drawsubpic = #328; /* - Draws a rescaled subsection of an image to the screen. */ - -#endif -#if defined(CSQC) || defined(MENU) -void(vector pivot, vector mins, vector maxs, string pic, vector rgb, float alpha, float angle) drawrotpic = #0:drawrotpic; /* - Draws an image rotating at the pivot. To rotate in the center, use mins+maxs of half the size with mins negated. Angle is in degrees. */ - -void(vector pivot, vector mins, vector maxs, string pic, vector txmin, vector txsize, vector rgb, vector alphaandangles) drawrotsubpic = #0:drawrotsubpic; /* - Overcomplicated draw function for over complicated people. Positions follow drawrotpic, while texture coords follow drawsubpic. Due to argument count limitations in builtins, the alpha value and angles are combined into separate fields of a vector (tip: use fteqcc's [alpha, angle] feature. */ - -#endif -#ifdef CSQC -#define getstati_punf(stnum) (float)(__variant)getstati(stnum) -int(float stnum) getstati = #330; /* - Retrieves the full precision of a stat registered as EV_INTEGER. */ - -#define getstatbits getstatf -float(float stnum, optional float firstbit, optional float bitcount) getstatf = #331; /* - Retrieves the numerical value of the given EV_FLOAT stat. If firstbit and bitcount are specified, then this builtin acts as getstati combined with itof, and which should be used for STAT_ITEMS (but not other stats). */ - -string(float stnum) getstats = #332; /* - Retrieves the value of the given EV_STRING stat, as a tempstring. - Older engines may use 4 consecutive integer stats, with a limit of 15 chars (yes, really. 15.), but FTE Quake uses a separate namespace for string stats and has a much higher length limit. */ - -__variant(float playernum, float statnum, float stattype) getplayerstat = #0:getplayerstat; /* - Retrieves a specific player's stat, matching the type specified on the server. This builtin is primarily intended for mvd playback where ALL players are known. Return value matches the specified EV_ stattype. For EV_ENTITY, world will be returned if the entity is not in the pvs, use type-punning with EV_INTEGER to get the entity number if you just want to see if its set. STAT_ITEMS should be queried as an EV_INTEGER on account of runes and items2 being packed into the upper bits. */ - -void(entity e, float mdlindex) setmodelindex = #333; /* - Sets a model by precache index instead of by name. Otherwise identical to setmodel. */ - -#endif -#if defined(CSQC) || defined(SSQC) -string(float mdlindex) modelnameforindex = #334; /* - Retrieves the name of the model based upon a precache index. This can be used to reduce csqc network traffic by enabling model matching (with getmodelindex). */ - -string(float sndindex) soundnameforindex = #0:soundnameforindex; /* - Retrieves the name of the sound based upon a precache index. This can be used to reduce csqc network traffic by enabling sound matching (with getsoundindex). */ - -float(string effectname) particleeffectnum = #335; /* Part of DP_ENT_TRAILEFFECTNUM, FTE_SV_POINTPARTICLES - Precaches the named particle effect. If your effect name is of the form 'foo.bar' then particles/foo.cfg will be loaded by the client if foo.bar was not already defined. - Different engines will have different particle systems, this specifies the QC API only. */ - -void(float effectnum, entity ent, vector start, vector end) trailparticles = #336; /* Part of FTE_SV_POINTPARTICLES - Draws the given effect between the two named points. If ent is not world, distances will be cached in the entity in order to avoid framerate dependancies. The entity is not otherwise used. */ - -void(float effectnum, vector origin, optional vector dir, optional float count) pointparticles = #337; /* Part of FTE_SV_POINTPARTICLES - Spawn a load of particles from the given effect at the given point traveling or aiming along the direction specified. The number of particles are scaled by the count argument. - For regular particles, the dir vector is multiplied by the 'veladd' property (while orgadd will push the particles along it). Decals will use it as a hint to align to the correct surface. In both cases, it should normally be a unit vector, but other lengths will still work. If it has length 0 then FTE will assume downwards. */ - -#endif -#ifdef CSQC -void(string s, ...) cprint = #338; /* - Print into the center of the screen just as ssqc's centerprint would appear. */ - -#endif -#if defined(CSQC) || defined(SSQC) -void(string s, ...) print = #339; /* Part of DP_SV_PRINT - Unconditionally print on the local system's console, even in ssqc (doesn't care about the value of the developer cvar). */ - -#endif -#ifdef CSQC -string(float keynum) keynumtostring = #340; /* - Returns a hunam-readable name for the given keycode, as a tempstring. */ - -#endif -#ifdef MENU -DEP string(float keynum) keynumtostring_csqc = #340; /* - Returns a hunam-readable name for the given keycode, as a tempstring. */ - -#endif -#ifdef CSQC -float(string keyname) stringtokeynum = #341; /* - Looks up the key name in the same way that the bind command would, returning the keycode for that key. */ - -#endif -#ifdef MENU -DEP float(string keyname) stringtokeynum_csqc = #341; /* - Looks up the key name in the same way that the bind command would, returning the keycode for that key. */ - -#endif -#if defined(CSQC) || defined(MENU) -string(float keynum) getkeybind = #342; /* - Returns the current binding for the given key (returning only the command executed when no modifiers are pressed). */ - -void(float usecursor, optional string cursorimage, optional vector hotspot, optional float scale) setcursormode = #343; /* - Pass TRUE if you want the engine to release the mouse cursor (absolute input events + touchscreen mode). Pass FALSE if you want the engine to grab the cursor (relative input events + standard looking). If the image name is specified, the engine will use that image for a cursor (use an empty string to clear it again), in a way that will not conflict with the console. Images specified this way will be hardware accelerated, if supported by the platform/port. */ - -float(float effective) getcursormode = #0:getcursormode; /* - Reports the cursor mode this module previously attempted to use. If 'effective' is true, reports the cursor mode currently active (if was overriden by a different module which has precidence, for instance, or if there is only a touchscreen and no mouse). */ - -#endif -#ifdef CSQC -vector() getmousepos = #344; /* - Nasty convoluted DP extension. Typically returns deltas instead of positions. Use CSQC_InputEvent instead for such things in csqc mods. */ - -#endif -#if defined(CSQC) || defined(MENU) -void(vector newpos) setmousepos = #0:setmousepos; /* - Warps the mouse cursor to the given location. Should normally only be done following setcursormode(TRUE,...). The warp MAY be visible through *_InputEvent, but normally be seen as an IE_ABSMOUSE event anyway. Not all systems support cursor warping (or even cursors), so this is a hint only and you should not depend upon it. */ - -#endif -#ifdef CSQC -float(float inputsequencenum) getinputstate = #345; /* - Looks up an input frame from the log, setting the input_* globals accordingly. - The sequence number range used for prediction should normally be servercommandframe < sequence <= clientcommandframe. - The sequence equal to clientcommandframe will change between input frames. */ - -void(float sens) setsensitivityscaler = #346; /* - Temporarily scales the player's mouse sensitivity based upon something like zoom, avoiding potential cvar saving and thus corruption. */ - -#endif -#if defined(CSQC) || defined(SSQC) -void(entity ent) runstandardplayerphysics = #347; /* - Perform the engine's standard player movement prediction upon the given entity using the input_* globals to describe movement. */ - -#endif -#ifdef CSQC -string(float playernum, string keyname) getplayerkeyvalue = #348; /* - Look up a player's userinfo, to discover things like their name, topcolor, bottomcolor, skin, team, *ver. - Also includes scoreboard info like frags, ping, pl, userid, entertime, as well as voipspeaking and voiploudness. */ - -float(float playernum, string keyname, optional float assumevalue) getplayerkeyfloat = #0:getplayerkeyfloat; /* - Cheaper version of getplayerkeyvalue that avoids the need for so many tempstrings. */ - -int(float playernum, string keyname, optional void *outptr, int size) getplayerkeyblob = #0:getplayerkeyblob; /* Part of FTE_INFOBLOBS - Obtains a copy of the full data blob. Will write up to size bytes but return the full size. Does not null terminate (but memalloc(ret+1) will, if you want to cast the buffer to a string), and the blob may contain embedded nulls. Ignores all special keys, returning only what is actually there. */ - -#endif -#if defined(CSQC) || defined(MENU) -void(float seat, string keyname, string newvalue) setlocaluserinfo = #0:setlocaluserinfo; /* - Change a userinfo key for the specified local player seat, equivelent to the setinfo console command. The server will normally forward the setting to other clients. */ - -string(float seat, string keyname) getlocaluserinfo = #0:getlocaluserinfo; /* - Reads a local userinfo key for the specified local player seat. This is not quite the same as getplayerkeyvalue, due to latency and possible serverside filtering. */ - -void(float seat, string keyname, void *outptr, int size) setlocaluserinfoblob = #0:setlocaluserinfoblob; /* Part of FTE_INFOBLOBS - Sets the userinfo key to a blob that may contain nulls etc. Keys with a leading underscore will be visible to only the server (for user-specific binary settings). */ - -int(float seat, string keyname, void *outptr, int maxsize) getlocaluserinfoblob = #0:getlocaluserinfoblob; /* Part of FTE_INFOBLOBS - Obtains a copy of the full data blob. Will write up to size bytes but return the full size. Does not null terminate (but memalloc(ret+1) will, if you want to cast the buffer to a string), and the blob may contain embedded nulls. Ignores all special keys, returning only what is actually there. */ - -#endif -#ifdef SSQC -int(string keyname, optional void *outptr, int size) getlocalinfo = #0:getlocalinfo; /* - Obtains a copy of a data blob (with spaces) from the server's private localinfo. Will write up to size bytes and return the actual size. Does not null terminate (but memalloc(ret+1) will, if you want to cast the buffer to a string), and the blob may contain embedded nulls. Ignores all special keys, returning only what is actually there. */ - -void(string keyname, optional void *outptr, int size) setlocalinfo = #0:setlocalinfo; /* - Changes the server's private localinfo. This data will be available for the following map, and will *usually* reload with saved games. */ - -#endif -#if defined(CSQC) || defined(MENU) -float() isdemo = #349; /* - Returns if the client is currently playing a demo or not. Returns 2 when playing an mvd (where other player's stats can be queried, or the pov can be changed freely). */ - -#endif -#ifdef CSQC -float() isserver = #350; /* - Returns non-zero whenever the local console can directly affect the server (ie: listen servers or single-player). Compat note: DP returns 0 for single-player. */ - -void(vector origin, vector forward, vector right, vector up, optional float reverbtype) SetListener = #351; /* - Sets the position of the view, as far as the audio subsystem is concerned. This should be called once per CSQC_UpdateView as it will otherwise revert to default. For reverbtype, see setup_reverb or treat as 'underwater'. */ - -typedef struct { - float flDensity; - float flDiffusion; - float flGain; - float flGainHF; - float flGainLF; - float flDecayTime; - float flDecayHFRatio; - float flDecayLFRatio; - float flReflectionsGain; - float flReflectionsDelay; - vector flReflectionsPan; - float flLateReverbGain; - float flLateReverbDelay; - vector flLateReverbPan; - float flEchoTime; - float flEchoDepth; - float flModulationTime; - float flModulationDepth; - float flAirAbsorptionGainHF; - float flHFReference; - float flLFReference; - float flRoomRolloffFactor; - int iDecayHFLimit; -} reverbinfo_t; -void(float reverbslot, reverbinfo_t *reverbinfo, int sizeofreverinfo_t) setup_reverb = #0:setup_reverb; /* Part of FTE_CSQC_REVERB - Reconfigures a reverb slot for weird effects. Slot 0 is reserved for no effects. Slot 1 is reserved for underwater effects. Reserved slots will be reinitialised on snd_restart, but can otherwise be changed. These reverb slots can be activated with SetListener. Note that reverb will currently only work when using OpenAL. */ - -#endif -void(string cmdname) registercommand = #352; /* - Register the given console command, for easy console use. - Console commands that are later used will invoke CSQC_ConsoleCommand/m_consolecommand/ConsoleCmd according to module. */ - -float(entity ent) wasfreed = #353; /* - Quickly check to see if the entity is currently free. This function is only valid during the half-second non-reuse window, after that it may give bad results. Try one second to make it more robust. */ - -#if defined(CSQC) || defined(SSQC) -string(string key) serverkey = #354; /* - Look up a key in the server's public serverinfo string. If the key contains binary data then it will be truncated at the first null. */ - -float(string key, optional float assumevalue) serverkeyfloat = #0:serverkeyfloat; /* - Version of serverkey that returns the value as a float (which avoids tempstrings). */ - -int(string key, optional void *ptr, int maxsize) serverkeyblob = #0:serverkeyblob; /* Part of FTE_INFOBLOBS - Version of serverkey that returns data as a blob (ie: binary data that may contain nulls). Returns the full blob size, even if truncated (pass maxsize=0 to query required storage). */ - -#endif -#ifdef SSQC -void(string key, void *ptr, optional int size) setserverkey = #0:setserverkey; /* - Changes the server's serverinfo. */ - -#endif -#ifdef CSQC -string(optional string resetstring) getentitytoken = #355; /* - Grab the next token in the map's entity lump. - If resetstring is not specified, the next token will be returned with no other sideeffects. - If empty, will reset from the map before returning the first token, probably {. - If not empty, will tokenize from that string instead. - Always returns tempstrings. */ - -#endif -#if defined(CSQC) || defined(MENU) -float(string s) findfont = #356; /* Part of DP_GFX_FONTS - Looks up a named font slot. Matches the actual font name as a last resort. */ - -float(string fontname, string fontmaps, string sizes, float slot, optional float fix_scale, optional float fix_voffset) loadfont = #357; /* Part of DP_GFX_FONTS - too convoluted for me to even try to explain correct usage. Try drawfont = loadfont("", "cour", "16", -1, 0, 0); to switch to the courier font (optimised for 16 virtual pixels high) ('cour' requires mscorefonts installed in linux). Additionally you can add "outline=1" as an extra token in the sizes string, to have more readable outlined fonts. */ - -#endif -#ifdef CSQC -void(string evname, string evargs, ...) sendevent = #359; /* - Invoke CSEv_evname_evargs in ssqc. evargs must be a string of initials refering to the types of the arguments to pass. v=vector, e=entity(.entnum field is sent), f=float, i=int. 6 arguments max - you can get more if you pack your floats into vectors. */ - -float() readbyte = #360; /* - Reads an unsigned 8-bit value, pair with WriteByte. */ - -float() readchar = #361; /* - Reads a signed 8-bit value. Paired with WriteChar. */ - -float() readshort = #362; /* - Reads a signed 16-bit value. Paired with WriteShort. */ - -float() readlong = #363; /* - Reads a signed 32-bit value. Paired with WriteLong or WriteInt. */ - -float() readcoord = #364; /* - Reads a value matching the unspecified precision written ONLY by WriteCoord. */ - -float() readangle = #365; /* - Reads a value matching the unspecified precision written ONLY by WriteAngle. */ - -string() readstring = #366; /* - Reads a null-terminated string. */ - -float() readfloat = #367; /* - Reads a float without any truncation nor conversions. Data MUST have originally been written with WriteFloat. */ - -__double() readdouble = #0:readdouble; /* - Reads a double-precision float without any truncation nor conversions. Data MUST have originally been written with WriteDouble. */ - -int() readint = #0:readint; /* - Reads a 32bit int without any conversions to float, otherwise interchangable with readlong. */ - -__int64() readint64 = #0:readint64; /* - Reads a 64bit signed int. Paired with WriteInt64. */ - -__uint64() readuint64 = #0:readuint64; /* - Reads a 64bit unsigned int. Paired with WriteUInt64. */ - -float() readentitynum = #368; /* - Reads the serverside index of an entity, paired with WriteEntity. There may be nothing else known about the entity yet, so the result typically needs to be saved as-is and re-looked up each frame. This can be done via getentity(NUM, GE_*) for non-csqc ents, or findentity(world,entnum,NUM) - both of which can fail due to latency. */ - -float(string modelname, float(float isnew) updatecallback, float flags) deltalisten = #371; /* - Specifies a per-modelindex callback to listen for engine-networking entity updates. Such entities are automatically interpolated by the engine (unless flags specifies not to). - The various standard entity fields will be overwritten each frame before the updatecallback function is called. */ - -float(vector org, float radius, vector rgb) dynamiclight_spawnstatic = #0:dynamiclight_spawnstatic; /* - Creates a static persistent light at the given position with the specified colour. Additional properties must be set via dynamiclight_set. */ - -__variant(float lno, float fld) dynamiclight_get = #372; /* - Retrieves a property from the given dynamic/rt light. Return type depends upon the light field requested. */ - -void(float lno, float fld, __variant value) dynamiclight_set = #373; /* - Changes a property on the given dynamic/rt light. Value type depends upon the light field to be changed. */ - -string(float efnum, float body) particleeffectquery = #374; /* - Retrieves either the name or the body of the effect with the given number. The effect body is regenerated from internal state, and can be changed before being reapplied via the localcmd builtin. */ - -void(string shadername, vector origin, vector up, vector side, vector rgb, float alpha) adddecal = #375; /* - Adds a temporary clipped decal shader to the scene, centered at the given point with given orientation. Will be drawn by the next renderscene call, and freed by the next clearscene call. */ - -#endif -#if defined(CSQC) || defined(MENU) -void(entity e, string skinfilename, optional string skindata) setcustomskin = #376; /* Part of FTE_QC_CUSTOMSKINS - Sets an entity's skin overrides to a new skin object. Releases the entities old skin (refcounted). */ - -#endif -#ifdef CSQC -float(string skinfilename, optional string skindata) loadcustomskin = #377; /* Part of FTE_QC_CUSTOMSKINS - Creates a new skin object and returns it. These are custom per-entity surface->shader lookups. The skinfilename/data should be in .skin format: - surfacename,shadername - makes the named surface use the named shader (legacy format for compat with q3) - replace "surfacename" "shadername" - non-legacy equivalent. - qwskin "foo" - use an unmodified quakeworld player skin (including crop+repalette rules) - q1lower 0xff0000 - specify an override for the entity's lower colour, in this case to red - q1upper 0x0000ff - specify an override for the entity's lower colour, in this case to blue - compose "surfacename" "shader" "imagename@x,y:w,h$s,t,s2,t2?r,g,b,a" - compose a skin texture from multiple images. - The texture is determined to be sufficient to hold the first named image, additional images can be named as extra tokens on the same line. - Use a + at the end of the line to continue reading image tokens from the next line also, the named shader must use 'map $diffuse' to read the composed texture (compatible with the defaultskin shader). Must be matched with a releasecustomskin call later, and is pointless without applycustomskin. */ - -void(entity e, float skinobj) applycustomskin = #378; /* Part of FTE_QC_CUSTOMSKINS - Updates the entity's custom skin (refcounted). */ - -void(float skinobj) releasecustomskin = #379; /* Part of FTE_QC_CUSTOMSKINS - Lets the engine know that the skin will no longer be needed. Thanks to refcounting any ents with the skin already applied will retain their skin until later changed. It is valid to destroy a skin just after applying it to an ent in the same function that it was created in, as the skin will only be destroyed once its refcount rops to 0. */ - -void(float devid, float amp_low, float amp_high, float duration) gp_rumble = #0:gp_rumble; /* - Sends a single rumble event to the game-pad specified in devid. Every time you call this, the previous effect is cancelled out. */ - -void(float devid, float left, float right, float duration) gp_rumbletriggers = #0:gp_rumbletriggers; /* - Makes the analog triggers rumble of the specified game-pad, like gp_rumble() one call cancels out the previous one on the device. */ - -void(float devid, vector color) gp_setledcolor = #0:gp_setledcolor; /* - Updates the game-pad LED color. */ - -void(float devid, /*const*/ void *data, int size) gp_settriggerfx = #0:gp_settriggerfx; /* - Sends a specific effect packet to the controller. On the PlayStation 5's DualSense that can adjust the tension on the analog triggers. */ - -#endif -__variant*(int size) memalloc = #384; /* Part of FTE_MEMALLOC - Allocate an arbitary block of memory */ - -void(__variant *ptr) memfree = #385; /* Part of FTE_MEMALLOC - Frees a block of memory that was allocated with memfree */ - -void(__variant *dst, __variant *src, int size) memcpy = #386; /* Part of FTE_MEMALLOC - Copys memory from one location to another */ - -void(__variant *dst, int val, int size) memfill8 = #387; /* Part of FTE_MEMALLOC - Sets an entire block of memory to a specified value. Pretty much always 0. */ - -__variant(__variant *dst, float ofs) memgetval = #388; /* - Looks up the 32bit value stored at a pointer-with-offset. */ - -void(__variant *dst, float ofs, __variant val) memsetval = #389; /* - Changes the 32bit value stored at the specified pointer-with-offset. */ - -__variant*(__variant *base, float ofs) memptradd = #390; /* - Perform some pointer maths. Woo. */ - -float(string s) memstrsize = #0:memstrsize; /* - strlen, except ignores utf-8 */ - -#if defined(CSQC) || defined(MENU) -string(string conname, string field, optional string newvalue) con_getset = #391; /* Part of FTE_CSQC_ALTCONSOLES - Reads or sets a property from a console object. The old value is returned. Iterrate through consoles with the 'next' field. Valid properties: title, name, next, unseen, markup, forceutf8, close, clear, hidden, linecount */ - -void(string conname, string messagefmt, ...) con_printf = #392; /* Part of FTE_CSQC_ALTCONSOLES - Prints onto a named console. */ - -void(string conname, vector pos, vector size, float fontsize) con_draw = #393; /* Part of FTE_CSQC_ALTCONSOLES - Draws the named console. */ - -float(string conname, float inevtype, float parama, float paramb, float paramc) con_input = #394; /* Part of FTE_CSQC_ALTCONSOLES - Forwards input events to the named console. Mouse updates should be absolute only. */ - -void(string newcaption) setwindowcaption = #0:setwindowcaption; /* Part of FTE_CSQC_WINDOWCAPTION - Replaces the title of the game window, as seen when task switching or just running in windowed mode. */ - -float() cvars_haveunsaved = #0:cvars_haveunsaved; /* - Returns true if any archived cvar has an unsaved value. */ - -#endif -float(entity e, float nowreadonly) entityprotection = #0:entityprotection; /* - Changes the protection on the specified entity to protect it from further edits from QC. The return value is the previous setting. Note that this can be used to unprotect the world, but doing so long term is not advised as you will no longer be able to detect invalid entity references. Also, world is not networked, so results might not be seen by clients (or in other words, world.avelocity_y=64 is a bad idea). */ - -#ifdef CSQC -string(vector pos) getlocationname = #0:getlocationname; /* - Looks up the specified position in the current map's .loc file and reports the nearest marked name. */ - -#endif -#ifdef MENU -void(int cliptype) clipboard_get = #0:clipboard_get; /* - Attempts to query the system clipboard. Any pasted text will be returned via Menu_InputEvent */ - -#endif -#if defined(CSQC) || defined(MENU) -void(int cliptype, string text) clipboard_set = #0:clipboard_set; /* - Changes the system clipboard to the specified text. */ - -#endif -#ifdef SSQC -entity(float entnum, optional __out float wasspawned) respawnedict = #0:respawnedict; /* - Acts like edict_num returning a specific entity number, but also marks it as spawned. If it was previously spawned then all of its prior field data will be LOST (you may wish to use wasfreed(edict_num(idx)) to check. */ - -#endif -#if defined(CSQC) || defined(SSQC) -entity(entity from, optional entity to) copyentity = #400; /* Part of DP_QC_COPYENTITY - Copies all fields from one entity to another. */ - -#endif -#ifdef SSQC -__deprecated("No RGB support.") void(entity ent, float colours) setcolor = #401; /* Part of DP_SV_SETCOLOR - Changes a player's colours. The bits 0-3 are the lower/trouser colour, bits 4-7 are the upper/shirt colours. */ - -#endif -#if defined(CSQC) || defined(SSQC) -entity(.string field, string match, optional .entity chainfield) findchain = #402; /* Part of DP_QC_FINDCHAIN*/ -entity(.float fld, float match, optional .entity chainfield) findchainfloat = #403; /* Part of DP_QC_FINDCHAINFLOAT*/ -void(vector org, string modelname, float startframe, float endframe, float framerate) effect = #404; /* Part of DP_SV_EFFECT - Spawns a self-animating sprite */ - -void(vector org, vector dir, float count) te_blood = #405; /* Part of DP_TE_BLOOD*/ -void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower = #406; /* Part of _DP_TE_BLOODSHOWER*/ -void(vector org, vector color) te_explosionrgb = #407; /* Part of DP_TE_EXPLOSIONRGB*/ -void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube = #408; /* Part of DP_TE_PARTICLECUBE*/ -void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain = #409; /* Part of DP_TE_PARTICLERAIN*/ -void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow = #410; /* Part of DP_TE_PARTICLESNOW*/ -void(vector org, vector vel, float howmany) te_spark = #411; /* Part of DP_TE_SPARK*/ -void(vector org) te_gunshotquad = #412; /* Part of _DP_TE_QUADEFFECTS1*/ -void(vector org) te_spikequad = #413; /* Part of _DP_TE_QUADEFFECTS1*/ -void(vector org) te_superspikequad = #414; /* Part of _DP_TE_QUADEFFECTS1*/ -void(vector org) te_explosionquad = #415; /* Part of _DP_TE_QUADEFFECTS1*/ -void(vector org) te_smallflash = #416; /* Part of DP_TE_SMALLFLASH*/ -void(vector org, float radius, float lifetime, vector color) te_customflash = #417; /* Part of DP_TE_CUSTOMFLASH*/ -void(vector org, optional float count) te_gunshot = #418; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ -void(vector org) te_spike = #419; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ -void(vector org) te_superspike = #420; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ -void(vector org) te_explosion = #421; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ -void(vector org) te_tarexplosion = #422; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ -void(vector org) te_wizspike = #423; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ -void(vector org) te_knightspike = #424; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ -void(vector org) te_lavasplash = #425; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ -void(vector org) te_teleport = #426; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ -void(vector org, float color, float colorlength) te_explosion2 = #427; /* Part of DP_TE_STANDARDEFFECTBUILTINS*/ -void(entity own, vector start, vector end) te_lightning1 = #428; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ -void(entity own, vector start, vector end) te_lightning2 = #429; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ -void(entity own, vector start, vector end) te_lightning3 = #430; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ -void(entity own, vector start, vector end) te_beam = #431; /* Part of DP_TE_STANDARDEFFECTBUILTINS*/ -void(vector dir) vectorvectors = #432; /* Part of DP_QC_VECTORVECTORS*/ -void(vector org) te_plasmaburn = #433; /* Part of _DP_TE_PLASMABURN*/ -float(entity e, float s) getsurfacenumpoints = #434; /* Part of DP_QC_GETSURFACE*/ -vector(entity e, float s, float n) getsurfacepoint = #435; /* Part of DP_QC_GETSURFACE*/ -vector(entity e, float s) getsurfacenormal = #436; /* Part of DP_QC_GETSURFACE*/ -string(entity e, float s) getsurfacetexture = #437; /* Part of DP_QC_GETSURFACE*/ -float(entity e, vector p) getsurfacenearpoint = #438; /* Part of DP_QC_GETSURFACE*/ -vector(entity e, float s, vector p) getsurfaceclippedpoint = #439; /* Part of DP_QC_GETSURFACE*/ -#endif -#ifdef MENU -strbuf() buf_create = #440; /* Part of DP_QC_STRINGBUFFERS*/ -void(strbuf bufhandle) buf_del = #441; /* Part of DP_QC_STRINGBUFFERS*/ -float(strbuf bufhandle) buf_getsize = #442; /* Part of DP_QC_STRINGBUFFERS*/ -void(strbuf bufhandle_from, float bufhandle_to) buf_copy = #443; /* Part of DP_QC_STRINGBUFFERS*/ -void(strbuf bufhandle, float sortprefixlen, float backward) buf_sort = #444; /* Part of DP_QC_STRINGBUFFERS*/ -string(strbuf bufhandle, string glue) buf_implode = #445; /* Part of DP_QC_STRINGBUFFERS*/ -string(strbuf bufhandle, float string_index) bufstr_get = #446; /* Part of DP_QC_STRINGBUFFERS*/ -void(strbuf bufhandle, float string_index, string str) bufstr_set = #447; /* Part of DP_QC_STRINGBUFFERS*/ -float(strbuf bufhandle, string str, float ordered) bufstr_add = #448; /* Part of DP_QC_STRINGBUFFERS*/ -void(strbuf bufhandle, float string_index) bufstr_free = #449; /* Part of DP_QC_STRINGBUFFERS*/ -float(string name) iscachedpic = #451; -string(string name, optional float flags) precache_pic = #452; -float(vector position, float character, vector scale, vector rgb, float alpha, optional float flag) drawcharacter = #454; -float(vector position, string text, vector scale, vector rgb, float alpha, optional float flag) drawrawstring = #455; -float(vector position, string pic, vector size, vector rgb, float alpha, optional float flag) drawpic = #456; -float(vector position, vector size, vector rgb, float alpha, optional float flag) drawfill = #457; -void(float x, float y, float width, float height) drawsetcliparea = #458; -void(void) drawresetcliparea = #459; -vector(string picname) drawgetimagesize = #460; -void(float width, vector pos1, vector pos2) drawline = #466; -float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring = #467; -float(string text, float usecolours, vector fontsize='8 8') stringwidth = #468; -void(vector pos, vector sz, string pic, vector srcpos, vector srcsz, vector rgb, float alpha, float flag) drawsubpic = #469; -#endif -#ifdef SSQC -void(entity e, string s) clientcommand = #440; /* Part of KRIMZON_SV_PARSECLIENTCOMMAND*/ -#endif -#if defined(CSQC) || defined(SSQC) -float(string s) tokenize = #441; /* Part of KRIMZON_SV_PARSECLIENTCOMMAND*/ -string(float n) argv = #442; /* Part of KRIMZON_SV_PARSECLIENTCOMMAND*/ -void(entity e, entity tagentity, string tagname) setattachment = #443; /* Part of DP_GFX_QUAKE3MODELTAGS*/ -searchhandle(string pattern, enumflags:float{SB_CASEINSENSITIVE=1<<0,SB_FULLPACKAGEPATH=1<<1,SB_ALLOWDUPES=1<<2,SB_FORCESEARCH=1<<3,SB_MULTISEARCH=1<<4,SB_NAMESORT=1<<5} flags, float quiet, optional string filterpackage) search_begin = #444; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE - initiate a filesystem scan based upon filenames. Be sure to call search_end on the returned handle. SB_FULLPACKAGEPATH interprets the filterpackage arg as a full package path to avoid gamedir ambiguity, equivelent to whichpack's WP_FULLPACKAGEPATH flag. SB_ALLOWDUPES allows returning multiple entries with the same name (but different package, useful with search_fopen). SB_FORCESEARCH requires use of the filterpackage and SB_FULLPACKAGEPATH flag, initiating searches from gamedirs/packages which are not currently active. */ - -void(searchhandle handle) search_end = #445; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE*/ -float(searchhandle handle) search_getsize = #446; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE - Retrieves the number of files that were found. */ - -string(searchhandle handle, float num) search_getfilename = #447; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE - Retrieves name of one of the files that was found by the initial search. */ - -#endif -float(searchhandle handle, float num) search_getfilesize = #0:search_getfilesize; /* Part of FTE_QC_FS_SEARCH_SIZEMTIME - Retrieves the size of one of the files that was found by the initial search. */ - -string(searchhandle handle, float num) search_getfilemtime = #0:search_getfilemtime; /* Part of FTE_QC_FS_SEARCH_SIZEMTIME - Retrieves modification time of one of the files. */ - -string(searchhandle handle, float num) search_getpackagename = #0:search_getpackagename; /* - Retrieves the name of the package containing the file. Search with SB_FULLPACKAGEPATH to see gamedir/package info */ - -filestream(searchhandle handle, float num) search_fopen = #0:search_fopen; /* - Opens the file directly, without getting confused about entries from other packages. Read access only. */ - -#if defined(CSQC) || defined(SSQC) -string(string cvarname) cvar_string = #448; /* Part of DP_QC_CVAR_STRING*/ -entity(entity start, .float fld, float match) findflags = #449; /* Part of DP_QC_FINDFLAGS*/ -entity(.float fld, float match, optional .entity chainfield) findchainflags = #450; /* Part of DP_QC_FINDCHAINFLAGS*/ -float(entity ent, string tagname) gettagindex = #451; /* Part of DP_QC_GETTAGINFO*/ -vector(entity ent, float tagindex) gettaginfo = #452; /* Part of DP_QC_GETTAGINFO - Obtains the current worldspace position+orientation of the bone or tag from the given entity. The return value is the world coord, v_forward, v_right, v_up are also set according to the bone/tag's orientation. */ - -#endif -#ifdef SSQC -void(entity player) dropclient = #453; /* Part of DP_SV_DROPCLIENT*/ -entity() spawnclient = #454; /* Part of DP_SV_BOTCLIENT*/ -float(entity client) clienttype = #455; /* Part of DP_SV_BOTCLIENT*/ -void(float target, string str) WriteUnterminatedString = #456; /* Part of DP_SV_WRITEUNTERMINATEDSTRING*/ -#endif -#if defined(CSQC) || defined(SSQC) -void(vector org, vector vel, float howmany) te_flamejet = #457; /* Part of _DP_TE_FLAMEJET*/ -entity(float entnum) edict_num = #459; /* Part of DP_QC_EDICT_NUM*/ -strbuf() buf_create = #460; /* Part of DP_QC_STRINGBUFFERS*/ -void(strbuf bufhandle) buf_del = #461; /* Part of DP_QC_STRINGBUFFERS*/ -float(strbuf bufhandle) buf_getsize = #462; /* Part of DP_QC_STRINGBUFFERS*/ -void(strbuf bufhandle_from, strbuf bufhandle_to) buf_copy = #463; /* Part of DP_QC_STRINGBUFFERS*/ -void(strbuf bufhandle, float sortprefixlen, float backward) buf_sort = #464; /* Part of DP_QC_STRINGBUFFERS*/ -string(strbuf bufhandle, string glue) buf_implode = #465; /* Part of DP_QC_STRINGBUFFERS*/ -string(strbuf bufhandle, float string_index) bufstr_get = #466; /* Part of DP_QC_STRINGBUFFERS*/ -void(strbuf bufhandle, float string_index, string str) bufstr_set = #467; /* Part of DP_QC_STRINGBUFFERS*/ -float(strbuf bufhandle, string str, float ordered) bufstr_add = #468; /* Part of DP_QC_STRINGBUFFERS*/ -void(strbuf bufhandle, float string_index) bufstr_free = #469; /* Part of DP_QC_STRINGBUFFERS*/ -#endif -float(float s) asin = #471; /* Part of DP_QC_ASINACOSATANATAN2TAN*/ -float(float c) acos = #472; /* Part of DP_QC_ASINACOSATANATAN2TAN*/ -float(float t) atan = #473; /* Part of DP_QC_ASINACOSATANATAN2TAN*/ -float(float c, float s) atan2 = #474; /* Part of DP_QC_ASINACOSATANATAN2TAN*/ -float(float a) tan = #475; /* Part of DP_QC_ASINACOSATANATAN2TAN - Forgive me father, for I have a sunbed and I'm not afraid to use it. */ - -float(string s) strlennocol = #476; /* Part of DP_QC_STRINGCOLORFUNCTIONS - Returns the number of characters in the string after any colour codes or other markup has been parsed. */ - -string(string s) strdecolorize = #477; /* Part of DP_QC_STRINGCOLORFUNCTIONS - Flattens any markup/colours, removing them from the string. */ - -string(float uselocaltime, string format, ...) strftime = #478; /* Part of DP_QC_STRFTIME*/ -float(string s, string separator1, ...) tokenizebyseparator = #479; /* Part of DP_QC_TOKENIZEBYSEPARATOR - Splits up the string using only the specified delimiters/separators. Multiple delimiters can be given, they are each considered equivelent (though should start with the longest if you want to do weird subseparator stuff). - The resulting tokens can be queried via argv (and argv_start|end_index builtins, if you want to determine which of the separators was present between two tokens). - Note that while an input string containing JUST a separator will return 2, a string with no delimiter will return 1, while (in FTE) an empty string will ALWAYS return 0. */ - -string(string s) strtolower = #480; /* Part of DP_QC_STRING_CASE_FUNCTIONS*/ -string(string s) strtoupper = #481; /* Part of DP_QC_STRING_CASE_FUNCTIONS*/ -#if defined(CSQC) || defined(SSQC) -string(string s) cvar_defstring = #482; /* Part of DP_QC_CVAR_DEFSTRING*/ -void(vector origin, string sample, float volume, float attenuation) pointsound = #483; /* Part of DP_SV_POINTSOUND*/ -#endif -string(string search, string replace, string subject) strreplace = #484; /* Part of DP_QC_STRREPLACE*/ -string(string search, string replace, string subject) strireplace = #485; /* Part of DP_QC_STRREPLACE*/ -#if defined(CSQC) || defined(SSQC) -vector(entity e, float s, float n, float a) getsurfacepointattribute = #486; /* Part of DP_QC_GETSURFACEPOINTATTRIBUTE*/ -#endif -#if defined(CSQC) || defined(MENU) -float(string name, optional string initialURI) gecko_create = #487; /* Part of DP_GECKO_SUPPORT - Create a new 'browser tab' shader with the specified name that can then be drawn via drawpic (shader should not already exist - including from map/model textures or disk). In order to function correctly, this builtin depends upon external plugins being available. Use gecko_navigate to navigate it to a page of your choosing. */ - -void(string name) gecko_destroy = #488; /* Part of DP_GECKO_SUPPORT - Destroy a shader. */ - -void(string name, string URI) gecko_navigate = #489; /* Part of DP_GECKO_SUPPORT - Sends a command to the media decoder attached to the specified shader. In the case of a browser decoder, this changes the url that the browser displays. 'cmd:[un]focus' will tell the decoder that it has focus. */ - -float(string name, float key, float eventtype, optional float charcode) gecko_keyevent = #490; /* Part of DP_GECKO_SUPPORT - Send a key event to a media decoder. This applies only to interactive decoders like browsers. */ - -void(string name, float x, float y) gecko_mousemove = #491; /* Part of DP_GECKO_SUPPORT - Sets a media decoder shader's mouse position. Values should be 0-1. */ - -void(string name, float w, float h) gecko_resize = #492; /* Part of DP_GECKO_SUPPORT - Request to resize a media decoder. */ - -vector(string name) gecko_get_texture_extent = #493; /* Part of DP_GECKO_SUPPORT - Retrieves a media decoder current image pixel sizes. */ - -string(string shadname, string propname) gecko_getproperty = #0:gecko_getproperty; /* - Queries the media decoder (especially browser ones) for decoder-specific properties. The cef plugin recognises url, title, status. */ - -#endif -#ifdef CSQC -float(string file, string id) cin_open = #0:cin_open; -void(string id) cin_close = #0:cin_close; -void(string id, float newstate) cin_setstate = #0:cin_setstate; -float(string id) cin_getstate = #0:cin_getstate; -void(string file) cin_restart = #0:cin_restart; -#endif -__deprecated("Use digest_hex") float(float caseinsensitive, string s, ...) crc16 = #494; /* Part of DP_QC_CRC16*/ -float(string name) cvar_type = #495; /* Part of DP_QC_CVAR_TYPE*/ -float() numentityfields = #496; /* Part of DP_QC_ENTITYDATA - Gives the number of named entity fields. Note that this is not the size of an entity, but rather just the number of unique names (ie: vectors use 4 names rather than 3). */ - -float(string fieldname) findentityfield = #0:findentityfield; /* - Find a field index by name. */ - -typedef .__variant field_t; -field_t(float fieldnum) entityfieldref = #0:entityfieldref; /* - Returns a field value that can be directly used to read entity fields. Be sure to validate the type with entityfieldtype before using. */ - -string(float fieldnum) entityfieldname = #497; /* Part of DP_QC_ENTITYDATA - Retrieves the name of the given entity field. */ - -float(float fieldnum) entityfieldtype = #498; /* Part of DP_QC_ENTITYDATA - Provides information about the type of the field specified by the field num. Returns one of the EV_ values. */ - -string(float fieldnum, entity ent) getentityfieldstring = #499; /* Part of DP_QC_ENTITYDATA*/ -float(float fieldnum, entity ent, string s) putentityfieldstring = #500; /* Part of DP_QC_ENTITYDATA*/ -#ifdef SSQC -void(float to, string s, float sz) WritePicture = #501; /* Part of DP_SV_WRITEPICTURE - Encodes the named image across the network as-is adhering to some size limit. In FTE, this simply writes the string and is equivelent to writestring and sz is ignored. WritePicture should be paired with ReadPicture in csqc. */ - -#endif -#ifdef CSQC -string() ReadPicture = #501; /* - Reads a picture that was written by ReadPicture, and returns a name that can be used in drawpic and other 2d drawing functions. In FTE, this acts as a readstring-with-downloadcheck - the image will appear normally once it has been downloaded, but its size may be incorrect until then. */ - -void(float effectindex, entity own, vector org_from, vector org_to, vector dir_from, vector dir_to, float countmultiplier, optional float flags) boxparticles = #502; -#endif -string(string filename, optional enumflags:float{WP_REFERENCEPACKAGE,WP_FULLPACKAGEPATH} flags) whichpack = #503; /* Part of DP_QC_WHICHPACK - Returns the pak file name that contains the file specified. progs/player.mdl will generally return something like 'pak0.pak'. If WP_REFERENCE, clients will automatically be told that the returned package should be pre-downloaded and used, even if allow_download_refpackages is not set. */ - -#ifdef CSQC -__variant(float entnum, float fieldnum) getentity = #504; /* - Looks up fields from non-csqc-visible entities. The entity will need to be within the player's pvs. fieldnum should be one of the GE_ constants. */ - -#endif -string(string in) uri_escape = #510; /* Part of DP_QC_URI_ESCAPE - Uses percent-encoding to encode any bytes in the input string which are not ascii alphanumeric, period, hyphen, or underscore. All other bytes will expand to eg '%20' for a single space char. This encoding scheme is compatible with http and other uris. */ - -string(string in) uri_unescape = #511; /* Part of DP_QC_URI_ESCAPE - Undo any percent-encoding in the input string, hopefully resulting in the same original sequence of bytes (and thus chars too). */ - -float(entity ent) num_for_edict = #512; -#define uri_post uri_get -float(string uril, float id, optional string postmimetype, optional string postdata) uri_get = #513; /* Part of DP_QC_URI_GET, DP_QC_URI_POST - uri_get() gets content from an URL and calls a callback "uri_get_callback" with it set as string; an unique ID of the transfer is returned - returns 1 on success, and then calls the callback with the ID, 0 or the HTTP status code, and the received data in a string - For a POST request, you will typically want the postmimetype set to application/x-www-form-urlencoded. - For a GET request, omit the mime+data entirely. - Consult your webserver/php/etc documentation for best-practise. */ - -float(string str) tokenize_console = #514; /* - Tokenize a string exactly as the console's tokenizer would do so. The regular tokenize builtin became bastardized for convienient string parsing, which resulted in a large disparity that can be exploited to bypass checks implemented in a naive SV_ParseClientCommand function, therefore you can use this builtin to make sure it exactly matches. */ - -float(float idx) argv_start_index = #515; /* - Returns the character index that the tokenized arg started at. */ - -float(float idx) argv_end_index = #516; /* - Returns the character index that the tokenized arg stopped at. */ - -void(strbuf strbuf, string pattern, string antipattern) buf_cvarlist = #517; -string(string cvarname) cvar_description = #518; /* - Retrieves the description of a cvar, which might be useful for tooltips or help files. This may still not be useful. */ - -#if defined(CSQC) || defined(SSQC) -float(optional float timetype) gettime = #519; -#endif -#ifdef CSQC -DEP string(float keynum) keynumtostring_omgwtf = #520; -__deprecated("Does not support modifiers") string(string command, optional float bindmap) findkeysforcommand = #521; /* - Returns a list of keycodes that perform the given console command in a format that can only be parsed via tokenize (NOT tokenize_console). This only and always returns two values - if only one key is actually bound, -1 will be returned. The bindmap argument is listed for compatibility with dp-specific defs, but is ignored in FTE. */ - -#endif -#if defined(CSQC) || defined(MENU) -string(string command, optional float bindmap) findkeysforcommandex = #0:findkeysforcommandex; /* - Returns a list of key bindings in keyname format instead of keynums. Use tokenize to parse. This list may contain modifiers. May return large numbers of keys. */ - -#endif -#if defined(CSQC) || defined(SSQC) -void(string s) loadfromdata = #529; /* - Reads a set of entities from the given string. This string should have the same format as a .ent file or a saved game. Entities will be spawned as required. If you need to see the entities that were created, you should use parseentitydata instead. */ - -void(string s) loadfromfile = #530; /* - Reads a set of entities from the named file. This file should have the same format as a .ent file or a saved game. Entities will be spawned as required. If you need to see the entities that were created, you should use parseentitydata instead. */ - -void(float pause) setpause = #531; /* - Sets whether the server should or should not be paused. This does not affect auto-paused things like when the console is down. */ - -#endif -#ifdef SSQC -float(string mname) precache_vwep_model = #532; /* Part of ZQ_VWEP*/ -#endif -float(float v, optional float base) log = #532; /* - Determines the logarithm of the input value according to the specified base. This can be used to calculate how much something was shifted by. */ - -#ifdef CSQC -float(entity e, float channel, string newsample, float volume, float attenuation, float pitchpct, float flags, float timeoffset) soundupdate = #0:soundupdate; /* - Changes the properties of the current sound being played on the given entity channel. newsample may be empty, and will be ignored in this case. timeoffset is relative to the current position (subtract the result of getsoundtime for absolute positions). Negative volume can be used to stop the sound. Return value is a fractional value based upon the number of audio devices that could be updated - test against TRUE rather than non-zero. */ - -float(entity e, float channel) getsoundtime = #533; /* - Returns the current playback time of the sample on the given entity's channel. Beware CHAN_AUTO (in csqc, channels are not limited by network protocol). */ - -float(entity e, float channel) getchannellevel = #0:getchannellevel; /* - Reports how load the sound's sample is at its current offset. */ - -#endif -#if defined(CSQC) || defined(MENU) -float(string sample) soundlength = #534; /* - Provides a way to query the duration of a sound sample, allowing you to set up a timer to chain samples. */ - -#endif -float(string filename, strbuf bufhandle) buf_loadfile = #535; /* - Appends the named file into a string buffer (which must have been created in advance). The return value merely says whether the file was readable. */ - -float(filestream filehandle, strbuf bufhandle, optional float startpos, optional float numstrings) buf_writefile = #536; /* - Writes the contents of a string buffer onto the end of the supplied filehandle (you must have already used fopen). Additional optional arguments permit you to constrain the writes to a subsection of the stringbuffer. */ - -float(float bufhandle, string match, float matchrule, float startpos, float step) bufstr_find = #537; /* - Looks for the first occurence of the specified string in the buffer, returning its index or -1 on failure. */ - -#ifdef SSQC -float(optional float forcestate) physics_supported = #0:physics_supported; /* - Queries whether rigid body physics is enabled or not. CSQC and SSQC may report different values. If the force argument is specified then the engine will try to activate or release physics (returning the new state, which may fail if plugins or dlls are missing). Note that restarting the physics engine is likely to result in hitches when collision trees get generated. The state may change if a plugin is disabled mid-map. */ - -#endif -#if defined(CSQC) || defined(SSQC) -void(entity e, float physics_enabled) physics_enable = #540; /* - Enable or disable the physics attached to a MOVETYPE_PHYSICS entity. Entities which have been disabled in this way will stop taking so much cpu time. */ - -void(entity e, vector force, vector relative_ofs) physics_addforce = #541; /* - Apply some impulse directional force upon a MOVETYPE_PHYSICS entity. */ - -void(entity e, vector torque) physics_addtorque = #542; /* - Apply some impulse rotational force upon a MOVETYPE_PHYSICS entity. */ - -#endif -#ifdef MENU -void(float dest) setkeydest = #601; -float() getkeydest = #602; -#endif -#if defined(CSQC) || defined(MENU) -void(float trg) setmousetarget = #603; -float() getmousetarget = #604; -#endif -void(.../*, string funcname*/) callfunction = #605; /* - Invokes the named function. The function name is always passed as the last parameter and must always be present. The others are passed to the named function as-is */ - -void(filestream fh, entity e) writetofile = #606; /* - Writes an entity's fields to the named frik_file file handle. */ - -float(string s) isfunction = #607; /* - Returns true if the named function exists and can be called with the callfunction builtin. */ - -#if defined(CSQC) || defined(MENU) -vector(float vidmode, optional float forfullscreen) getresolution = #608; /* - Supposed to query the driver for supported video modes. FTE does not query drivers in this way, nor would it trust drivers anyway. */ - -#endif -#ifdef CSQC -DEP string(float keynum) keynumtostring_menu = #609; -#endif -#ifdef MENU -string(float keynum) keynumtostring = #609; /* - Converts a qscancode key number into a mostly-human-readable name, matching the bind command. */ - -string(string command, optional float bindmap) findkeysforcommand = #610; -#endif -#if defined(CSQC) || defined(MENU) -float(float type) gethostcachevalue = #611; /* Part of FTE_CSQC_SERVERBROWSER*/ -string(float type, float hostnr) gethostcachestring = #612; /* Part of FTE_CSQC_SERVERBROWSER*/ -#endif -float(entity e, string s, optional float offset) parseentitydata = #613; /* - Reads a single entity's fields into an already-spawned entity. s should contain field pairs like in a saved game: {"foo1" "bar" "foo2" "5"}. Returns <=0 on failure, otherwise returns the offset in the string that was read to. */ - -string(entity e) generateentitydata = #0:generateentitydata; /* - Dumps the entities fields into a string which can later be parsed with parseentitydata. */ - -#ifdef MENU -float(string key) stringtokeynum = #614; /* - Returns the qscancode of a key from its name. Names are identical to the bind command. ctrl/shift/alt modifiers are ignored. */ - -#endif -#ifdef CSQC -float(string key) stringtokeynum_menu = #614; -#endif -#if defined(CSQC) || defined(MENU) -void() resethostcachemasks = #615; /* Part of FTE_CSQC_SERVERBROWSER*/ -void(float mask, float fld, string str, float op) sethostcachemaskstring = #616; /* Part of FTE_CSQC_SERVERBROWSER*/ -void(float mask, float fld, float num, float op) sethostcachemasknumber = #617; /* Part of FTE_CSQC_SERVERBROWSER*/ -void() resorthostcache = #618; /* Part of FTE_CSQC_SERVERBROWSER*/ -void(float fld, float descending) sethostcachesort = #619; /* Part of FTE_CSQC_SERVERBROWSER*/ -void(optional float dopurge) refreshhostcache = #620; /* Part of FTE_CSQC_SERVERBROWSER*/ -float(float fld, float hostnr) gethostcachenumber = #621; /* Part of FTE_CSQC_SERVERBROWSER*/ -float(string key) gethostcacheindexforkey = #622; /* Part of FTE_CSQC_SERVERBROWSER*/ -void(string key) addwantedhostcachekey = #623; /* Part of FTE_CSQC_SERVERBROWSER*/ -string() getextresponse = #624; /* Part of FTE_CSQC_SERVERBROWSER*/ -#endif -string(string dnsname, optional float defport) netaddress_resolve = #625; -#if defined(CSQC) || defined(MENU) -string(float n, float prop) getgamedirinfo = #626; /* - Queries properties about an indexed gamedir (or -1 for the current gamedir). Returns null strings when out of bounds. Use the GDDI_* constants for the prop arg. */ - -string(int n, int prop) getpackagemanagerinfo = #0:getpackagemanagerinfo; /* - Queries information about a package from the engine's package manager subsystem. Actions can be taken via the pkg console command. */ - -#endif -string(string fmt, ...) sprintf = #627; /* Part of DP_QC_SPRINTF - 'prints' to a formatted temp-string. Mostly acts as in C, however %d assumes floats (fteqcc has arg checking. Use it.). - type conversions: l=arg is an int, h=arg is a float, and will work as a prefix for any float or int representation. - float representations: d=decimal, e,E=exponent-notation, f,F=floating-point notation, g,G=terse float, c=char code, x,X=hex - other representations: i=int, s=string, S=quoted and marked-up string, v=vector, p=pointer - so %ld will accept an int arg, while %hi will expect a float arg. - entities, fields, and functions will generally need to be printed as ints with %i. */ - -#if defined(CSQC) || defined(SSQC) -float(entity e, float s) getsurfacenumtriangles = #628; -vector(entity e, float s, float n) getsurfacetriangle = #629; -#endif -#if defined(CSQC) || defined(MENU) -float(float key, string bind, optional float bindmap, optional float modifier) setkeybind = #630; -vector() getbindmaps = #631; -float(vector bm) setbindmaps = #632; -#endif -string(string digest, string data, ...) digest_hex = #639; -string(string digest, void *data, int length) digest_ptr = #0:digest_ptr; /* - Calculates the digest of a single contiguous block of memory (including nulls) using the specified hash function. */ - -float(string src, string dst) fcopy = #650; /* - Equivelent to fopen+fread+fwrite+fclose from QC (ie: reads from $gamedir/data/ or $gamedir, but always writes to $gamedir/data/ ) */ - -float(string src, string dst) frename = #651; /* - Renames the file, returning 0 on success. Both paths are relative to the data/ subdir. */ - -float(string fname) fremove = #652; /* - Deletes the named file - path is relative to data/ subdir, like fopen's FILE_WRITE. Returns 0 on success. */ - -float(string fname) fexists = #653; /* - Returns true if it exists inside the default writable path. Use whichpack for greater portability. */ - -float(string path) rmtree = #654; /* - Dangerous, but sandboxed to data/ */ - -#if defined(CSQC) || defined(MENU) -const float K_TAB = 9; -const float K_ENTER = 13; -const float K_ESCAPE = 27; -const float K_SPACE = 32; -const float K_BACKSPACE = 127; -const float K_UPARROW = 128; -const float K_DOWNARROW = 129; -const float K_LEFTARROW = 130; -const float K_RIGHTARROW = 131; -const float K_LALT = 132; -const float K_RALT = -280; -const float K_LCTRL = 133; -const float K_RCTRL = -281; -const float K_LSHIFT = 134; -const float K_RSHIFT = -282; -const float K_F1 = 135; -const float K_F2 = 136; -const float K_F3 = 137; -const float K_F4 = 138; -const float K_F5 = 139; -const float K_F6 = 140; -const float K_F7 = 141; -const float K_F8 = 142; -const float K_F9 = 143; -const float K_F10 = 144; -const float K_F11 = 145; -const float K_F12 = 146; -const float K_INS = 147; -const float K_DEL = 148; -const float K_PGDN = 149; -const float K_PGUP = 150; -const float K_HOME = 151; -const float K_END = 152; -const float K_KP_HOME = 164; -const float K_KP_UPARROW = 165; -const float K_KP_PGUP = 166; -const float K_KP_LEFTARROW = 161; -const float K_KP_5 = 162; -const float K_KP_RIGHTARROW = 163; -const float K_KP_END = 158; -const float K_KP_DOWNARROW = 159; -const float K_KP_PGDN = 160; -const float K_KP_ENTER = 172; -const float K_KP_INS = 157; -const float K_KP_DEL = 167; -const float K_KP_SLASH = 168; -const float K_KP_MINUS = 170; -const float K_KP_PLUS = 171; -const float K_KP_NUMLOCK = 154; -const float K_KP_STAR = 169; -const float K_KP_EQUALS = 173; -const float K_MOUSE1 = 512; -const float K_MOUSE2 = 513; -const float K_MOUSE3 = 514; -const float K_MOUSE4 = 517; -const float K_MOUSE5 = 518; -const float K_MOUSE6 = 519; -const float K_MOUSE7 = 520; -const float K_MOUSE8 = 521; -const float K_MOUSE9 = 522; -const float K_MOUSE10 = 523; -const float K_MWHEELUP = 515; -const float K_MWHEELDOWN = 516; -const float K_LWIN = -274; -const float K_RWIN = -275; -const float K_APP = -276; -const float K_SEARCH = -277; -const float K_POWER = -130; -const float K_VOLUP = -278; -const float K_VOLDOWN = -279; -const float K_JOY1 = 768; -const float K_JOY2 = 769; -const float K_JOY3 = 770; -const float K_JOY4 = 771; -const float K_JOY5 = 772; -const float K_JOY6 = 773; -const float K_JOY7 = 774; -const float K_JOY8 = 775; -const float K_JOY9 = 776; -const float K_JOY10 = 777; -const float K_JOY11 = 778; -const float K_JOY12 = 779; -const float K_JOY13 = 780; -const float K_JOY14 = 781; -const float K_JOY15 = 782; -const float K_JOY16 = 783; -const float K_JOY17 = 784; -const float K_JOY18 = 785; -const float K_JOY19 = 786; -const float K_JOY20 = 787; -const float K_JOY21 = 788; -const float K_JOY22 = 789; -const float K_JOY23 = 790; -const float K_JOY24 = 791; -const float K_JOY25 = 792; -const float K_JOY26 = 793; -const float K_JOY27 = 794; -const float K_JOY28 = 795; -const float K_JOY29 = 796; -const float K_JOY30 = 797; -const float K_JOY31 = 798; -const float K_JOY32 = 799; -const float K_AUX1 = 800; -const float K_AUX2 = 801; -const float K_AUX3 = 802; -const float K_AUX4 = 803; -const float K_AUX5 = 804; -const float K_AUX6 = 805; -const float K_AUX7 = 806; -const float K_AUX8 = 807; -const float K_AUX9 = 808; -const float K_AUX10 = 809; -const float K_AUX11 = 810; -const float K_AUX12 = 811; -const float K_AUX13 = 812; -const float K_AUX14 = 813; -const float K_AUX15 = 814; -const float K_AUX16 = 815; -const float K_PAUSE = 153; -const float K_PRINTSCREEN = 174; -const float K_CAPSLOCK = 155; -const float K_SCROLLLOCK = 156; -const float K_SEMICOLON = 59; -const float K_PLUS = 43; -const float K_MINUS = 45; -const float K_APOSTROPHE = 39; -const float K_QUOTES = 34; -const float K_TILDE = 126; -const float K_BACKQUOTE = 96; -const float K_BACKSLASH = 92; -const float K_GP_A = 826; -const float K_GP_B = 827; -const float K_GP_X = 828; -const float K_GP_Y = 829; -const float K_GP_LSHOULDER = 824; -const float K_GP_RSHOULDER = 825; -const float K_GP_LTRIGGER = 830; -const float K_GP_RTRIGGER = 831; -const float K_GP_BACK = 821; -const float K_GP_START = 820; -const float K_GP_LTHUMB = 822; -const float K_GP_RTHUMB = 823; -const float K_GP_DPAD_UP = 816; -const float K_GP_DPAD_DOWN = 817; -const float K_GP_DPAD_LEFT = 818; -const float K_GP_DPAD_RIGHT = 819; -const float K_GP_GUIDE = -238; -const float K_GP_SHARE = -248; -const float K_GP_PADDLE1 = -249; -const float K_GP_PADDLE2 = -250; -const float K_GP_PADDLE3 = -251; -const float K_GP_PADDLE4 = -252; -const float K_GP_TOUCHPAD = -253; -const float K_GP_UNKNOWN = -264; -const float K_GP_LTHUMB_UP = 832; -const float K_GP_LTHUMB_DOWN = 833; -const float K_GP_LTHUMB_LEFT = 834; -const float K_GP_LTHUMB_RIGHT = 835; -const float K_GP_RTHUMB_UP = 836; -const float K_GP_RTHUMB_DOWN = 837; -const float K_GP_RTHUMB_LEFT = 838; -const float K_GP_RTHUMB_RIGHT = 839; -#endif -#ifdef _ACCESSORS -accessor strbuf : float -{ - inline get float asfloat[float idx] = {return stof(bufstr_get(this, idx));}; - inline set float asfloat[float idx] = {bufstr_set(this, idx, ftos(value));}; - get string[float] = bufstr_get; - set string[float] = bufstr_set; - get float length = buf_getsize; -}; -accessor searchhandle : float -{ - get string[float] = search_getfilename; - get float length = search_getsize; -}; -accessor hashtable : float -{ - inline get vector v[string key] = {return hash_get(this, key, '0 0 0', EV_VECTOR);}; - inline set vector v[string key] = {hash_add(this, key, value, HASH_REPLACE|EV_VECTOR);}; - inline get string s[string key] = {return hash_get(this, key, "", EV_STRING);}; - inline set string s[string key] = {hash_add(this, key, value, HASH_REPLACE|EV_STRING);}; - inline get float f[string key] = {return hash_get(this, key, 0.0, EV_FLOAT);}; - inline set float f[string key] = {hash_add(this, key, value, HASH_REPLACE|EV_FLOAT);}; - inline get __variant[string key] = {return hash_get(this, key, __NULL__);}; - inline set __variant[string key] = {hash_add(this, key, value, HASH_REPLACE);}; -}; -accessor infostring : string -{ - get string[string] = infoget; - inline set& string[string fld] = {this = infoadd(this, fld, value);}; -}; -accessor filestream : float -{ - get string = fgets; - inline set string = {fputs(this,value);}; -}; -#endif -accessor jsonnode : json_t -{ - inline get json_type_e type = json_get_value_type; - inline get string s = json_get_string; - inline get float f = json_get_float; - inline get __int i = json_get_integer; - inline get __int length = json_get_length; - inline get jsonnode a[__int key] = json_get_child_at_index; - inline get jsonnode[string key] = json_find_object_child; - inline get string name = json_get_name; -}; -#undef DEP_CSQC -#undef FTEDEP -#undef DEP -#pragma noref 0 - -typedef enum -{ - false, - true -} bool; +-separated key/value pairs (use tokenizebyseparator). Return __NULL__ to let the engine handle it, an empty string for a 404, and any other text for a regular 200 response. */ +#endif +#if defined(CSQC) || defined(SSQC) +void(float prevprogs) init; /* Part of FTE_MULTIPROGS. Called as soon as a progs is loaded, called at a time when entities are not valid. This is the only time when it is safe to call addprogs without field assignment. As it is also called as part of addprogs, this also gives you a chance to hook functions in modules that are already loaded (via externget+externget). */ +void() initents; /* Part of FTE_MULTIPROGS. Called after fields have been finalized. This is the first point at which it is safe to call spawn(), and is called before any entity fields have been parsed. You can use this entrypoint to send notifications to other modules. */ +#endif +#ifdef MENU +void() m_init; +void() m_shutdown; +void(vector screensize) m_draw; /* Provides the menuqc with a chance to draw. Will be called even if the menu does not have focus, so be sure to avoid that. COMPAT: screensize is not provided in DP. */ +void(vector screensize, float opaque) m_drawloading; /* Additional drawing function to draw loading screens. If opaque is set, then this function must ensure that the entire screen is overdrawn (even if just by a black drawfill). */ +void(string rendererdescription) Menu_RendererRestarted; /* Called by the engine after the video was restarted. This serves to notify the MenuQC that any render targets that it may have cached were purged, and will need to be regenerated. */ +float(float evtype, float scanx, float chary, float devid) Menu_InputEvent; /* If present, this is called instead of m_keydown and m_keyup +Called whenever a key is pressed, the mouse is moved, etc. evtype will be one of the IE_* constants. The other arguments vary depending on the evtype. Key presses are not guarenteed to have both scan and unichar values set at the same time. */ +__deprecated("Use Menu_InputEvent") void(float scan, float chr) m_keydown; +__deprecated("Use Menu_InputEvent") void(float scan, float chr) m_keyup; +void(float wantmode) m_toggle; +float(string cmd) m_consolecommand; +float(float idx) m_gethostcachecategory; +#endif +#ifdef SSQC +float parm17, parm18, parm19, parm20, parm21, parm22, parm23, parm24, parm25, parm26, parm27, parm28, parm29, parm30, parm31, parm32; /* Additional spawn parms, following the same parmN theme. */ +float parm33, parm34, parm35, parm36, parm37, parm38, parm39, parm40, parm41, parm42, parm43, parm44, parm45, parm46, parm47, parm48; +float parm49, parm50, parm51, parm52, parm53, parm54, parm55, parm56, parm57, parm58, parm59, parm60, parm61, parm62, parm63, parm64; +string parm_string; /* Like the regular parmN globals, but preserves string contents. */ +string startspot; /* Receives the value of the second argument to changelevel from the previous map. */ +var float dimension_send; /* Used by multicast functionality. Multicasts (and related builtins that multicast internally) will only be sent to players where (player.dimension_see & dimension_send) is non-zero. */ +//var float dimension_default = 255; +/* Default dimension bitmask */ +__unused var string __fullspawndata; /* Set by the engine before calls to spawn functions, and is most easily parsed with the tokenize builtin. This allows you to handle halflife's multiple-fields-with-the-same-name (or target-specific fields). */ +#endif +#if defined(CSQC) || defined(SSQC) +__used var float physics_mode = 2; /* 0: original csqc - physics are not run +1: DP-compat. Thinks occur, but not true movetypes. +2: movetypes occur just as they do in ssqc. */ +#endif +#ifdef CSQC +float gamespeed; /* Set by the engine, this is the value of the sv_gamespeed cvar */ +float numclientseats; /* This is the number of splitscreen clients currently running on this client. */ +#endif +#if defined(CSQC) || defined(MENU) +var vector drawfontscale = '1 1 0'; /* Specifies a scaler for all text rendering. There are other ways to implement this. */ +float drawfont; /* Allows you to choose exactly which font is to be used to draw text. Fonts can be registered/allocated with the loadfont builtin. */ +const float FONT_DEFAULT = 0; +#endif +#if defined(NQSSQC) +entity newmis; /* ssqc global */ +#endif +#if defined(CSQC) || defined(QWSSQC) +float deathmatch; /* ssqc global */ +float coop; /* ssqc global */ +#endif +#if defined(QWSSQC) +float teamplay; /* ssqc global */ +#endif +#if defined(CSQC) || defined(SSQC) +int trace_endcontentsi; /* ssqc global */ +int trace_surfaceflagsi; /* ssqc global */ +string trace_surfacename; /* ssqc global */ +float cycle_wrapped; /* ssqc global */ +#endif +#ifdef CSQC +float dimension_default; /* ssqc global */ +#endif +#if defined(CSQC) || defined(SSQC) +unsigned int input_weapon; /* ssqc global */ +float input_lightlevel; /* ssqc global */ +vector input_cursor_screen; /* ssqc global */ +vector input_cursor_trace_start; /* ssqc global */ +vector input_cursor_trace_endpos; /* ssqc global */ +float input_cursor_entitynumber; /* ssqc global */ +unsigned int input_head_status; /* ssqc global */ +vector input_head_origin; /* ssqc global */ +vector input_head_angles; /* ssqc global */ +vector input_head_velocity; /* ssqc global */ +vector input_head_avelocity; /* ssqc global */ +unsigned int input_head_weapon; /* ssqc global */ +unsigned int input_left_status; /* ssqc global */ +vector input_left_origin; /* ssqc global */ +vector input_left_angles; /* ssqc global */ +vector input_left_velocity; /* ssqc global */ +vector input_left_avelocity; /* ssqc global */ +unsigned int input_left_weapon; /* ssqc global */ +unsigned int input_right_status; /* ssqc global */ +vector input_right_origin; /* ssqc global */ +vector input_right_angles; /* ssqc global */ +vector input_right_velocity; /* ssqc global */ +vector input_right_avelocity; /* ssqc global */ +unsigned int input_right_weapon; /* ssqc global */ +#endif +#ifdef SSQC +float trace_endcontentsf; /* ssqc global */ +float trace_surfaceflagsf; /* ssqc global */ +#endif +#if defined(CSQC) || defined(SSQC) +string trace_dphittexturename; /* ssqc global */ +#endif +#ifdef SSQC +float trace_dpstartcontents; /* ssqc global */ +float trace_dphitcontents; /* ssqc global */ +float trace_dphitq3surfaceflags; /* ssqc global */ +#endif +#ifdef CSQC +float(vector angles, float isdelta) CSQC_Parse_SetAngles; +void(float playernum) CSQC_PlayerInfoChanged; +void() CSQC_ServerInfoChanged; +DEP("use CSQC_Event_Sound") float(float channel, string soundname, vector pos, float vol, float attenuation, float flags) CSQC_ServerSound; +void(int entidx, string newentdata) CSQC_MapEntityEdited; +float clframetime; +float servertime; +float serverprevtime; +float serverdeltatime; +DEP("Does not support mod-specific contents.") float trace_dpstartcontents; +DEP("Does not support mod-specific contents.") float trace_dphitcontents; +DEP("Does not support mod-specific surface flags") float trace_dphitq3surfaceflags; +DEP("Does not support all mod-specific surface flags.") float trace_surfaceflagsf; +DEP("Does not support all mod-specific contents.") float trace_endcontentsf; +float intermission_time; +vector pmove_mins; +vector pmove_maxs; +float pmove_jump_held; +float pmove_waterjumptime; +float input_clienttime; +float autocvar_vid_conwidth; +float autocvar_vid_conheight; +#endif +const float TRUE = 1; +const float FALSE = 0; /* File not found... */ +const float M_PI = 3.14159; /* Mathematica Pi constant. */ +#if defined(CSQC) || defined(SSQC) +const float MOVETYPE_NONE = 0; +const float MOVETYPE_WALK = 3; +const float MOVETYPE_STEP = 4; +const float MOVETYPE_FLY = 5; +const float MOVETYPE_TOSS = 6; +const float MOVETYPE_PUSH = 7; +const float MOVETYPE_NOCLIP = 8; +const float MOVETYPE_FLYMISSILE = 9; +const float MOVETYPE_BOUNCE = 10; +const float MOVETYPE_BOUNCEMISSILE = 11; +const float MOVETYPE_FOLLOW = 12; +const float MOVETYPE_6DOF = 30; /* A glorified MOVETYPE_FLY. Players using this movetype will get some flightsim-like physics, with fully independant rotations (order-dependant transforms). */ +const float MOVETYPE_WALLWALK = 31; /* Players using this movetype will be able to orient themselves to walls, and then run up them. */ +const float MOVETYPE_PHYSICS = 32; /* Enable the use of ODE physics upon this entity. */ +const float SOLID_NOT = 0; +const float SOLID_TRIGGER = 1; +const float SOLID_BBOX = 2; +const float SOLID_SLIDEBOX = 3; +const float SOLID_BSP = 4; /* Does not collide against other SOLID_BSP entities. Normally paired with MOVETYPE_PUSH. */ +const float SOLID_CORPSE = 5; /* Non-solid to SOLID_SLIDEBOX or other SOLID_CORPSE entities. For hitscan weapons to hit corpses, change the player's .hitcontentsmaski value to include CONTENTBIT_CORPSE, perform the traceline, then revert the player's .solid value. */ +__deprecated("Obsoleted by .skin=CONTENTS_LADDER") const float SOLID_LADDER = 20; /* Obsolete and may be removed at some point. Use skin=CONTENT_LADDER and solid_bsp or solid_trigger instead. */ +const float SOLID_PORTAL = 21; /* CSG subtraction volume combined with entity transformations on impact. */ +const float SOLID_BSPTRIGGER = 22; /* For complex-shaped trigger volumes, instead of being a pure aabb. */ +const float SOLID_PHYSICS_BOX = 32; +const float SOLID_PHYSICS_SPHERE = 33; +const float SOLID_PHYSICS_CAPSULE = 34; +const float SOLID_PHYSICS_TRIMESH = 35; +const float SOLID_PHYSICS_CYLINDER = 36; +const float GEOMTYPE_NONE = -1; +const float GEOMTYPE_SOLID = 0; +const float GEOMTYPE_BOX = 1; +const float GEOMTYPE_SPHERE = 2; +const float GEOMTYPE_CAPSULE = 3; +const float GEOMTYPE_TRIMESH = 4; +const float GEOMTYPE_CYLINDER = 5; +const float GEOMTYPE_CAPSULE_X = 6; +const float GEOMTYPE_CAPSULE_Y = 7; +const float GEOMTYPE_CAPSULE_Z = 8; +const float GEOMTYPE_CYLINDER_X = 9; +const float GEOMTYPE_CYLINDER_Y = 10; +const float GEOMTYPE_CYLINDER_Z = 11; +const float JOINTTYPE_FIXED = -1; +const float JOINTTYPE_POINT = 1; +const float JOINTTYPE_HINGE = 2; +const float JOINTTYPE_SLIDER = 3; +const float JOINTTYPE_UNIVERSAL = 4; +const float JOINTTYPE_HINGE2 = 5; +#endif +#ifdef CSQC +const float GE_MAXENTS = -1; /* Valid for getentity, ignores the entity argument. Returns the maximum number of entities which may be valid, to avoid having to poll 65k when only 100 are used. */ +const float GE_ACTIVE = 0; /* Valid for getentity. Returns whether this entity is known to the client or not. */ +const float GE_ORIGIN = 1; /* Valid for getentity. Returns the interpolated .origin. */ +const float GE_FORWARD = 2; /* Valid for getentity. Returns the interpolated forward vector. */ +const float GE_RIGHT = 3; /* Valid for getentity. Returns the entity's right vector. */ +const float GE_UP = 4; /* Valid for getentity. Returns the entity's up vector. */ +const float GE_SCALE = 5; /* Valid for getentity. Returns the entity .scale. */ +const float GE_ORIGINANDVECTORS = 6; /* Valid for getentity. Returns interpolated .origin, but also sets v_forward, v_right, and v_up accordingly. Use vectoangles(v_forward,v_up) to determine the angles. */ +const float GE_ALPHA = 7; /* Valid for getentity. Returns the entity alpha. */ +const float GE_COLORMOD = 8; /* Valid for getentity. Returns the colormod vector. */ +const float GE_PANTSCOLOR = 9; /* Valid for getentity. Returns the entity's lower color (from .colormap), as a palette range value. */ +const float GE_SHIRTCOLOR = 10; /* Valid for getentity. Returns the entity's lower color (from .colormap), as a palette range value. */ +const float GE_SKIN = 11; /* Valid for getentity. Returns the entity's .skin index. */ +const float GE_MINS = 12; /* Valid for getentity. Guesses the entity's .min vector. */ +const float GE_MAXS = 13; /* Valid for getentity. Guesses the entity's .max vector. */ +const float GE_ABSMIN = 14; /* Valid for getentity. Guesses the entity's .absmin vector. */ +const float GE_ABSMAX = 15; /* Valid for getentity. Guesses the entity's .absmax vector. */ +const float GE_MODELINDEX = 200; /* Valid for getentity. Guesses the entity's .modelindex float. */ +const float GE_MODELINDEX2 = 201; /* Valid for getentity. Guesses the entity's .vw_index float. */ +const float GE_EFFECTS = 202; /* Valid for getentity. Guesses the entity's .effects float. */ +const float GE_FRAME = 203; /* Valid for getentity. Guesses the entity's .frame float. */ +const float GE_ANGLES = 204; /* Valid for getentity. Guesses the entity's .angles vector. */ +const float GE_FATNESS = 205; /* Valid for getentity. Guesses the entity's .fatness float. */ +const float GE_DRAWFLAGS = 206; /* Valid for getentity. Guesses the entity's .drawflags float. */ +const float GE_ABSLIGHT = 207; /* Valid for getentity. Guesses the entity's .abslight float. */ +const float GE_GLOWMOD = 208; /* Valid for getentity. Guesses the entity's .glowmod vector. */ +const float GE_GLOWSIZE = 209; /* Valid for getentity. Guesses the entity's .glowsize float. */ +const float GE_GLOWCOLOUR = 210; /* Valid for getentity. Guesses the entity's .glowcolor float. */ +const float GE_RTSTYLE = 211; /* Valid for getentity. Guesses the entity's .style float. */ +const float GE_RTPFLAGS = 212; /* Valid for getentity. Guesses the entity's .pflags float. */ +const float GE_RTCOLOUR = 213; /* Valid for getentity. Guesses the entity's .color vector. */ +const float GE_RTRADIUS = 214; /* Valid for getentity. Guesses the entity's .light_lev float. */ +const float GE_TAGENTITY = 215; /* Valid for getentity. Guesses the entity's .tag_entity float. */ +const float GE_TAGINDEX = 216; /* Valid for getentity. Guesses the entity's .tag_index float. */ +const float GE_GRAVITYDIR = 217; /* Valid for getentity. Guesses the entity's .gravitydir vector. */ +const float GE_TRAILEFFECTNUM = 218; /* Valid for getentity. Guesses the entity's .traileffectnum float. */ +#endif +#ifdef SSQC +const float DAMAGE_NO = 0; +const float DAMAGE_YES = 1; +const float DAMAGE_AIM = 2; +#endif +#if defined(CSQC) || defined(SSQC) +const float CONTENT_EMPTY = -1; +const float CONTENT_SOLID = -2; +const float CONTENT_WATER = -3; +const float CONTENT_SLIME = -4; +const float CONTENT_LAVA = -5; +const float CONTENT_SKY = -6; +const float CONTENT_LADDER = -16; /* If this value is assigned to a solid_bsp's .skin field, the entity will become a ladder volume. */ +const int CONTENTBIT_NONE = 0x00000000i; +const int CONTENTBIT_SOLID = 0x00000001i; +const int CONTENTBIT_LAVA = 0x00000008i; +const int CONTENTBIT_SLIME = 0x00000010i; +const int CONTENTBIT_WATER = 0x00000020i; +const int CONTENTBIT_FTELADDER = 0x00004000i; /* Content bit used for .skin=CONTENT_LADDER entities. */ +const int CONTENTBIT_PLAYERCLIP = 0x00010000i; +const int CONTENTBIT_MONSTERCLIP = 0x00020000i; +const int CONTENTBIT_BODY = 0x02000000i; /* Content bit that indicates collisions against SOLID_BBOX/SOLID_SLIDEBOX entities. */ +const int CONTENTBIT_CORPSE = 0x04000000i; /* Content bit that indicates collisions against SOLID_CORPSE entities. */ +const int CONTENTBIT_Q2LADDER = 0x20000000i; /* Content bit specific to q2bsp (conflicts with q3bsp contents so use with caution). */ +const int CONTENTBIT_SKY = 0x80000000i; /* Content bit somewhat specific to q1bsp (aliases to NODROP in q3bsp), but you should probably check surfaceflags&SURF_SKY as well for q2+q3bsp too. */ +const int CONTENTBITS_POINTSOLID = CONTENTBIT_SOLID|0x00000002i|CONTENTBIT_BODY; /* Bits that traceline would normally consider solid */ +const int CONTENTBITS_BOXSOLID = CONTENTBIT_SOLID|0x00000002i|CONTENTBIT_BODY|CONTENTBIT_PLAYERCLIP; /* Bits that tracebox would normally consider solid */ +const int CONTENTBITS_FLUID = CONTENTBIT_WATER|CONTENTBIT_SLIME|CONTENTBIT_LAVA|CONTENTBIT_SKY; +const float SPA_POSITION = 0; /* These SPA_* constants are to specify which attribute is returned by the getsurfacepointattribute builtin */ +const float SPA_S_AXIS = 1; +const float SPA_T_AXIS = 2; +const float SPA_R_AXIS = 3; /* aka: SPA_NORMAL */ +const float SPA_TEXCOORDS0 = 4; +const float SPA_LIGHTMAP0_TEXCOORDS = 5; +const float SPA_LIGHTMAP0_COLOR = 6; +const float CHAN_AUTO = 0; /* The automatic channel, play as many sounds on this channel as you want, and they'll all play, however the other channels will replace each other. */ +const float CHAN_WEAPON = 1; +const float CHAN_VOICE = 2; +const float CHAN_ITEM = 3; +const float CHAN_BODY = 4; +#endif +#if defined(QWSSQC) +const float CHANF_RELIABLE = 8; /* Only valid if the flags argument is not specified. The sound will be sent reliably, which is important if it is intended to replace looping sounds on doors etc. */ +#endif +#ifdef SSQC +const float SOUNDFLAG_RELIABLE = 1; /* The sound will be sent reliably, and without regard to phs. */ +#endif +#ifdef CSQC +const float SOUNDFLAG_ABSVOLUME = 16; /* The sample's volume is not scaled by the volume cvar. Use with caution */ +#endif +#if defined(CSQC) || defined(SSQC) +const float SOUNDFLAG_FORCELOOP = 2; /* The sound will restart once it reaches the end of the sample. */ +const float SOUNDFLAG_NOSPACIALISE = 4; /* The different audio channels are played at the same volume regardless of which way the player is facing, without needing to use 0 attenuation. */ +const float SOUNDFLAG_NOREVERB = 32; /* Disables the use of underwater/reverb effects on this sound effect. */ +const float SOUNDFLAG_FOLLOW = 64; /* The sound's origin will updated to follow the emitting entity. */ +const float SOUNDFLAG_NOREPLACE = 128; /* Sounds started with this flag will be ignored when there's already a sound playing on that same ent-channel. */ +#endif +#ifdef SSQC +const float SOUNDFLAG_UNICAST = 256; /* The sound will be sent only by the player specified by msg_entity. Spectators and related splitscreen players will also hear the sound. */ +const float SOUNDFLAG_SENDVELOCITY = 512; /* The entity's current velocity will be sent to the client, only useful if doppler is enabled. */ +#endif +#if defined(CSQC) || defined(SSQC) +const float ATTN_NONE = 0; /* Sounds with this attenuation can be heard throughout the map */ +const float ATTN_NORM = 1; /* Standard attenuation */ +const float ATTN_IDLE = 2; /* Extra attenuation so that sounds don't travel too far. */ +const float ATTN_STATIC = 3; /* Even more attenuation to avoid torches drowing out everything else throughout the map. */ +#endif +#ifdef SSQC +const float SVC_CGAMEPACKET = 83; /* Direct ssqc->csqc message. Must only be multicast. The data triggers a CSQC_Parse_Event call in the csqc for the csqc to read the contents. The server *may* insert length information for clients connected via proxies which are not able to cope with custom csqc payloads. This should only ever be used in conjunction with the MSG_MULTICAST destination. */ +#endif +#if defined(CSQC) || defined(SSQC) +const float TE_SPIKE = 0; +const float TE_SUPERSPIKE = 1; +const float TE_GUNSHOT = 2; +const float TE_EXPLOSION = 3; +const float TE_TAREXPLOSION = 4; +const float TE_LIGHTNING1 = 5; +const float TE_LIGHTNING2 = 6; +const float TE_WIZSPIKE = 7; +const float TE_KNIGHTSPIKE = 8; +const float TE_LIGHTNING3 = 9; +const float TE_LAVASPLASH = 10; +const float TE_TELEPORT = 11; +#endif +#if defined(CSQC) || defined(QWSSQC) +const float TE_BLOOD = 12; +#endif +#if defined(NQSSQC) +const float TE_EXPLOSION2 = 12; +#endif +#if defined(CSQC) || defined(QWSSQC) +const float TE_LIGHTNINGBLOOD = 13; +#endif +#if defined(NQSSQC) +const float TE_BEAM = 13; +const float MSG_BROADCAST = 0; /* The byte(s) will be unreliably sent to all players. MSG_ constants are valid arguments to the Write* builtin family. */ +const float MSG_ONE = 1; /* The byte(s) will be reliably sent to the player specified in the msg_entity global. WARNING: in quakeworld servers without network preparsing enabled, this can result in illegible server messages (due to individual reliable messages being split between multiple backbuffers/packets). NQ has larger reliable buffers which avoids this issue, but still kicks the client. */ +const float MSG_ALL = 2; /* The byte(s) will be reliably sent to all players. */ +#endif +#if defined(QWSSQC) +__deprecated("Use MSG_MULTICAST+multicast(MULTICAST_*)") const float MSG_BROADCAST; /* The byte(s) will be unreliably sent to all players. MSG_ constants are valid arguments to the Write* builtin family. */ +__deprecated("Use MSG_MULTICAST+multicast(MULTICAST_ONE_R)") const float MSG_ONE = 1; /* The byte(s) will be reliably sent to the player specified in the msg_entity global. WARNING: in quakeworld servers without network preparsing enabled, this can result in illegible server messages (due to individual reliable messages being split between multiple backbuffers/packets). NQ has larger reliable buffers which avoids this issue, but still kicks the client. */ +__deprecated("Use MSG_MULTICAST+multicast(MULTICAST_ALL)") const float MSG_ALL = 2; /* The byte(s) will be reliably sent to all players. */ +#endif +#ifdef SSQC +const float MSG_INIT = 3; /* The byte(s) will be written into the signon buffer. Clients will see these messages when they connect later. This buffer is only flushed on map changes, so spamming it _WILL_ result in overflows. */ +const float MSG_MULTICAST = 4; /* The byte(s) will be written into the multicast buffer for more selective sending. Messages sent this way will never be split across packets, and using this for csqc-only messages will not break protocol translation. */ +const float MSG_ENTITY = 5; /* The byte(s) will be written into the entity buffer. This is a special value used only inside 'SendEntity' functions. */ +const float MULTICAST_ALL = 0; /* The multicast message is unreliably sent to all players. MULTICAST_ constants are valid arguments for the multicast builtin, which ignores the specified origin when given this constant. */ +const float MULTICAST_PHS = 1; /* The multicast message is unreliably sent to only players that can potentially hear the specified origin. Its quite loose. */ +const float MULTICAST_PVS = 2; /* The multicast message is unreliably sent to only players that can potentially see the specified origin. */ +const float MULTICAST_ONE = 6; /* The multicast message is unreliably sent to the player (AND ALL TRACKING SPECTATORS) specified in the msg_entity global. The specified origin is ignored. */ +const float MULTICAST_ONE_NOSPECS = 9; /* The multicast message is unreliably sent to the player specified in the msg_entity global. The specified origin is ignored. */ +const float MULTICAST_ALL_R = 3; /* The multicast message is reliably sent to all players. The specified origin is ignored. */ +const float MULTICAST_PHS_R = 4; /* The multicast message is reliably sent to only players that can potentially hear the specified origin. Players might still not receive it if they are out of range. */ +const float MULTICAST_PVS_R = 5; /* The multicast message is reliably sent to only players that can potentially see the specified origin. Players might still not receive it if they cannot see the event. */ +const float MULTICAST_ONE_R = 7; /* The multicast message is reliably sent to the player (AND ALL TRACKING SPECTATORS) specified in the msg_entity global. The specified origin is ignored */ +const float MULTICAST_ONE_R_NOSPECS = 10; /* The multicast message is reliably sent to the player specified in the msg_entity global. The specified origin is ignored */ +#endif +#if defined(QWSSQC) +const float PRINT_LOW = 0; +const float PRINT_MEDIUM = 1; +const float PRINT_HIGH = 2; +const float PRINT_CHAT = 3; +#endif +#ifdef SSQC +const float PVSF_NORMALPVS = 0; /* Filter first by PVS, then filter this entity using tracelines if sv_cullentities is enabled. */ +const float PVSF_NOTRACECHECK = 1; /* Filter strictly by PVS. */ +const float PVSF_USEPHS = 2; /* Send if we're close enough to be able to hear this entity. */ +const float PVSF_IGNOREPVS = 3; /* Ignores pvs. This entity is visible whereever you are on the map. Updates will be sent regardless of pvs or phs */ +const float PVSF_NOREMOVE = 128; /* Once visible to a client, this entity will remain visible. This can be useful for csqc and corpses. While this flag is set, no CSQC_Remove events will be sent for the entity, but this does NOT mean that it will still receive further updates while outside of the pvs. */ +const string INFOKEY_P_IP = "ip"; /* The apparent ip address of the client. This may be a proxy's ip address. */ +const string INFOKEY_P_REALIP = "realip"; /* If sv_getrealip is set, this gives the ip as determine using that algorithm. */ +const string INFOKEY_P_CSQCACTIVE = "csqcactive"; /* Client has csqc enabled. CSQC ents etc will be sent to this player. */ +const string INFOKEY_P_SVPING = "svping"; +const string INFOKEY_P_GUID = "guid"; /* Some hash string which should be reasonably unique to this player's quake installation. */ +const string INFOKEY_P_CHALLENGE = "challenge"; +const string INFOKEY_P_USERID = "*userid"; +const string INFOKEY_P_DOWNLOADPCT = "download"; /* The client's download percentage for the current file. Additional files are not known. */ +const string INFOKEY_P_TRUSTLEVEL = "trustlevel"; +const string INFOKEY_P_PROTOCOL = "protocol"; /* The network protocol the client is using to connect to the server. */ +const string INFOKEY_P_VIP = "*VIP"; /* 1 if the player has the VIP 'penalty'. */ +const string INFOKEY_P_ISMUTED = "*ismuted"; /* 1 if the player has the 'mute' penalty and is not allowed to use the say/say_team commands. */ +const string INFOKEY_P_ISDEAF = "*isdeaf"; /* 1 if the player has the 'deaf' penalty and cannot see other people's say/say_team commands. */ +const string INFOKEY_P_ISCRIPPLED = "*ismuted"; /* 1 if the player has the cripple penalty, and their movement values are ignored (.movement is locked to 0). */ +const string INFOKEY_P_ISCUFFED = "*ismuted"; /* 1 if the player has the cuff penalty, and is unable to attack or use impulses(.button0 and .impulse fields are locked to 0). */ +const string INFOKEY_P_ISLAGGED = "*ismuted"; /* 1 if the player has the fakelag penalty and has an extra 200ms of lag. */ +#endif +#if defined(CSQC) || defined(SSQC) +const string INFOKEY_P_PING = "ping"; /* The player's ping time, in milliseconds. */ +const string INFOKEY_P_NAME = "name"; /* The player's name. */ +const string INFOKEY_P_SPECTATOR = "*spectator"; /* Whether the player is a spectator or not. */ +const string INFOKEY_P_TOPCOLOR = "topcolor"; /* The player's upper/shirt colour (palette index). */ +const string INFOKEY_P_BOTTOMCOLOR = "bottomcolor"; /* The player's lower/pants/trouser colour (palette index). */ +#endif +#ifdef CSQC +const string INFOKEY_P_TOPCOLOR_RGB = "topcolor_rgb"; /* The player's upper/shirt colour as an rgb value in a format usable with stov. */ +const string INFOKEY_P_BOTTOMCOLOR_RGB = "bottomcolor_rgb"; /* The player's lower/pants/trouser colour as an rgb value in a format usable with stov. */ +const string INFOKEY_P_MUTED = "ignored"; /* 0: we can see the result of the player's say/say_team commands. 1: we see no say/say_team messages from this player. Use the ignore command to toggle this value. */ +const string INFOKEY_P_VOIP_MUTED = "vignored"; /* 0: we can hear this player when they speak (assuming voip is generally enabled). 1: we ignore everything this player says. Use cl_voip_mute to change the values. */ +const string INFOKEY_P_ENTERTIME = "entertime"; /* Reads the timestamp at which the player entered the game, in terms of csqc's time global. */ +const string INFOKEY_P_FRAGS = "frags"; /* Reads a player's frag count. */ +const string INFOKEY_P_PACKETLOSS = "pl"; /* Reads a player's packetloss, as a percentage. */ +const string INFOKEY_P_VOIPSPEAKING = "voipspeaking"; /* Boolean value that says whether the given player is currently sending voice information. */ +const string INFOKEY_P_VOIPLOUDNESS = "voiploudness"; /* Only valid for the local player. Gives a value between 0 and 1 to indicate to the user how loud their mic is. */ +const string SERVERKEY_IP = "ip"; /* The address of the server we connected to. */ +const string SERVERKEY_SERVERNAME = "servername"; /* The hostname that was last passed to the connect command. */ +const string SERVERKEY_CONSTATE = "constate"; /* The current connection state. Will be set to one of: disconnected (menu-only mode), active (gamestate received and loaded), connecting(connecting, downloading, or precaching content, aka: loading screen). */ +const string SERVERKEY_TRANSFERRING = "transferring"; /* Set to the hostname of the server that we are attempting to connect or transfer to. */ +const string SERVERKEY_LOADSTATE = "loadstate"; /* loadstage, loading image name, current step, max steps +Stages are: 1=connecting, 2=serverside, 3=clientside +Key will be empty if we are not loading. */ +const string SERVERKEY_PAUSESTATE = "pausestate"; /* 1 if the server claimed to be paused. 0 otherwise */ +const string SERVERKEY_DLSTATE = "dlstate"; /* The progress of any current downloads. Empty string if no download is active, otherwise a tokenizable string containing this info: +files-remaining, total-size, unknown-sizes-flag, file-localname, file-remotename, file-percent, file-rate, file-received-bytes, file-total-bytes +If the current file info is omitted, then we are waiting for a download to start. */ +const string SERVERKEY_PROTOCOL = "protocol"; /* The protocol we are connected to the server with. */ +const string SERVERKEY_MAXPLAYERS = "maxplayers"; /* The number of player/spectator slots allocated on the server. */ +#endif +#ifdef SSQC +const float STUFFCMD_IGNOREINDEMO = 1; /* This stuffcmd will NOT be written to mvds/qtv. */ +const float STUFFCMD_DEMOONLY = 2; /* This stuffcmd will ONLY be written into mvds/qtv streams. */ +const float STUFFCMD_BROADCAST = 4; /* The stuffcmd will be broadcast server-wide (according to the mvd filters). */ +const float STUFFCMD_UNRELIABLE = 8; /* The stuffcmd might not arrive. It might also get there faster than ones sent over the reliable channel. */ +#endif +#if defined(CSQC) || defined(SSQC) +const float FL_FLY = 1; +const float FL_SWIM = 2; +const float FL_CLIENT = 8; +const float FL_INWATER = 16; +const float FL_MONSTER = 32; +#endif +#ifdef SSQC +const float FL_GODMODE = 64; +const float FL_NOTARGET = 128; +#endif +#if defined(CSQC) || defined(SSQC) +const float FL_ITEM = 256; +const float FL_ONGROUND = 512; +const float FL_PARTIALGROUND = 1024; +const float FL_WATERJUMP = 2048; +#endif +#if defined(NQSSQC) +const float FL_JUMPRELEASED = 4096; +#endif +#if defined(CSQC) || defined(SSQC) +const float FL_FINDABLE_NONSOLID = 16384; /* Allows this entity to be found with findradius */ +#endif +#ifdef SSQC +const float FL_LAGGEDMOVE = 65536; /* Enables anti-lag on rockets etc. */ +#endif +#if defined(CSQC) || defined(SSQC) +const float MOVE_NORMAL = 0; +const float MOVE_NOMONSTERS = 1; /* The trace will ignore all non-solid_bsp entities. */ +const float MOVE_MISSILE = 2; /* The trace will use a bbox size of +/- 15 against entities with FL_MONSTER set. */ +const float MOVE_WORLDONLY = 3; /* The trace will ignore everything but the worldmodel. This is useful for to prevent the q3bsp pvs+culling issues that come with spectator modes leaving the world . */ +const float MOVE_HITMODEL = 4; /* Traces will impact the actual mesh of the model instead of merely their bounding box. Should generally only be used for tracelines. Note that this flag is unreliable as an object can animate through projectiles. The bounding box MUST be set to completely encompass the entity or those extra areas will be non-solid (leaving a hole for things to go through). */ +const float MOVE_TRIGGERS = 16; /* This trace type will impact only triggers. It will ignore non-solid entities. */ +const float MOVE_EVERYTHING = 32; /* This type of trace will hit solids and triggers alike. Even non-solid entities. */ +#endif +#ifdef SSQC +const float MOVE_LAGGED = 64; /* Will use antilag based upon the player's latency. Traces will be performed against old positions for entities instead of their current origin. */ +#endif +#if defined(CSQC) || defined(SSQC) +const float MOVE_ENTCHAIN = 128; /* Returns a list of entities impacted via the trace_ent.chain field */ +const float MOVE_OTHERONLY = 256; /* Traces that use this trace type will collide against *only* the entity specified via the 'other' global, and will ignore all owner/solid_not/dimension etc rules, they will still adhere to contents and bsp/bbox rules though. */ +#endif +const float CVAR_TYPEFLAG_EXISTS = 1; /* Cvar name actually exists. */ +const float CVAR_TYPEFLAG_SAVED = 2; /* Cvar is flaged for archival (might need cfg_save to actually save). */ +const float CVAR_TYPEFLAG_PRIVATE = 4; /* QC is not allowed to read. */ +const float CVAR_TYPEFLAG_ENGINE = 8; /* Cvar was created by the engine itself (not user/mod created). */ +const float CVAR_TYPEFLAG_HASDESCRIPTION = 16; /* cvar_description will return something (hopefully) useful. */ +const float CVAR_TYPEFLAG_READONLY = 32; /* cvar may not be changed by qc. */ +const float RESTYPE_MODEL = 0; /* RESTYPE_* constants are used as arguments with the resourcestatus builtin. */ +const float RESTYPE_SOUND = 1; /* precache_sound */ +const float RESTYPE_PARTICLE = 2; /* particleeffectnum */ +#if defined(CSQC) || defined(MENU) +const float RESTYPE_PIC = 3; /* precache_pic. Status results are an amalgomation of the textures used by the named shader. */ +const float RESTYPE_SKIN = 4; /* setcustomskin */ +const float RESTYPE_TEXTURE = 5; /* Individual textures within shaders. These are not directly usable, but may be named as part of a skin file, or a shader. */ +#endif +const float RESSTATE_NOTKNOWN = 0; /* RESSTATE_* constants are return values from the resourcestatus builtin. The engine doesn't know about the resource if it is in this state. This means you will need to precache it. Attempting to use it anyway may result in warnings, errors, or silently succeed, depending on engine version and resource type. */ +const float RESSTATE_NOTLOADED = 1; /* The resource was precached, but has been flushed and there has not been an attempt to reload it. If you use the resource normally, chances are it'll be loaded but at the cost of a stall. */ +const float RESSTATE_LOADING = 2; /* Resources in this this state are queued for loading, and will be loaded at the engine's convienience. If you attempt to query the resource now, the engine will stall until the result is available. sounds in this state may be delayed, while models/pics/shaders may be invisible. */ +const float RESSTATE_FAILED = 3; /* Resources in this state are unusable/could not be loaded. You will get placeholders or dummy results. Queries will not stall the engine. The engine may display placeholder content. */ +const float RESSTATE_LOADED = 4; /* Resources in this state are finally usable, everything will work okay. Hurrah. Queries will not stall the engine. */ +#if defined(CSQC) || defined(SSQC) +const float EF_BRIGHTFIELD = 1; +#endif +#if defined(CSQC) || defined(NQSSQC) +const float EF_MUZZLEFLASH = 2; +#endif +#if defined(CSQC) || defined(SSQC) +const float EF_BRIGHTLIGHT = 4; +const float EF_DIMLIGHT = 8; +#endif +#if defined(QWSSQC) +const float EF_FLAG1 = 16; +const float EF_FLAG2 = 32; +#endif +#if defined(CSQC) || defined(NQSSQC) +const float EF_NODRAW = 16; /* Disables drawing of the model. Does NOT work on QW players. */ +#endif +#if defined(CSQC) || defined(SSQC) +const float EF_ADDITIVE = 32; /* The entity will be drawn with an additive blend. This is NOT supported on players in any quakeworld engine. */ +const float EF_BLUE = 64; /* A blue glow */ +const float EF_RED = 128; /* A red glow */ +const float EF_GREEN = 262144; /* A green glow */ +const float EF_FULLBRIGHT = 512; /* This entity will ignore lighting */ +const float EF_NOSHADOW = 4096; /* This entity will not cast shadows */ +const float EF_NODEPTHTEST = 8192; /* This entity will be drawn over the top of other things that are closer. */ +#endif +#ifdef SSQC +const float EF_NOMODELFLAGS = 8388608; /* Surpresses the normal flags specified in the model. */ +#endif +#if defined(CSQC) || defined(SSQC) +const float MF_ROCKET = 1; +const float MF_GRENADE = 2; +const float MF_GIB = 4; /* Regular blood trail */ +const float MF_ROTATE = 8; +const float MF_TRACER = 16; /* AKA: green scrag trail */ +const float MF_ZOMGIB = 32; /* Dark blood trail */ +const float MF_TRACER2 = 64; /* AKA: hellknight projectile trail */ +const float MF_TRACER3 = 128; /* AKA: purple vore trail */ +#endif +#ifdef SSQC +DEP_CSQC const float SL_ORG_TL = 20; /* Used with showpic etc, specifies that the x+y values are relative to the top-left of the screen */ +DEP_CSQC const float SL_ORG_TR = 21; +DEP_CSQC const float SL_ORG_BL = 22; +DEP_CSQC const float SL_ORG_BR = 23; +DEP_CSQC const float SL_ORG_MM = 24; +DEP_CSQC const float SL_ORG_TM = 25; +DEP_CSQC const float SL_ORG_BM = 26; +DEP_CSQC const float SL_ORG_ML = 27; +DEP_CSQC const float SL_ORG_MR = 28; +#endif +#if defined(CSQC) || defined(SSQC) +const float PFLAGS_NOSHADOW = 1; /* Associated RT lights attached will not cast shadows, making them significantly faster to draw. */ +const float PFLAGS_CORONA = 2; /* Enables support of coronas on the associated rtlights. */ +#endif +#ifdef SSQC +const float PFLAGS_FULLDYNAMIC = 128; /* When set in self.pflags, enables fully-customised dynamic lights. Custom rtlight information is not otherwise used. */ +#endif +const float EV_STRING = 1; +const float EV_FLOAT = 2; +const float EV_VECTOR = 3; +const float EV_ENTITY = 4; +const float EV_FIELD = 5; +const float EV_FUNCTION = 6; +const float EV_POINTER = 7; +const float EV_INTEGER = 8; +const float EV_UINT = 9; +const float EV_INT64 = 10; +const float EV_UINT64 = 11; +const float EV_DOUBLE = 12; +hashtable gamestate; /* Special hash table index for hash_add and hash_get. Entries in this table will persist over map changes (and doesn't need to be created/deleted). */ +const float HASH_REPLACE = 256; /* Used with hash_add. Attempts to remove the old value instead of adding two values for a single key. */ +const float HASH_ADD = 512; /* Used with hash_add. The new entry will be inserted in addition to the existing entry. */ +#ifdef CSQC +const float STAT_HEALTH = 0; /* Player's health. */ +const float STAT_WEAPONMODELI = 2; /* This is the modelindex of the current viewmodel (renamed from the original name 'STAT_WEAPON' due to confusions). */ +const float STAT_AMMO = 3; /* player.currentammo */ +const float STAT_ARMOR = 4; +const float STAT_WEAPONFRAME = 5; +const float STAT_SHELLS = 6; +const float STAT_NAILS = 7; +const float STAT_ROCKETS = 8; +const float STAT_CELLS = 9; +const float STAT_ACTIVEWEAPON = 10; /* player.weapon */ +const float STAT_TOTALSECRETS = 11; +const float STAT_TOTALMONSTERS = 12; +const float STAT_FOUNDSECRETS = 13; +const float STAT_KILLEDMONSTERS = 14; +const float STAT_ITEMS = 15; /* self.items | (self.items2<<23). In order to decode this stat properly, you need to use getstatbits(STAT_ITEMS,0,23) to read self.items, and getstatbits(STAT_ITEMS,23,11) to read self.items2 or getstatbits(STAT_ITEMS,28,4) to read the visible part of serverflags, whichever is applicable. */ +const float STAT_VIEWHEIGHT = 16; /* player.view_ofs_z */ +const float STAT_VIEW2 = 20; /* This stat contains the number of the entity in the server's .view2 field. */ +const float STAT_VIEWZOOM = 21; /* Scales fov and sensitiity. Part of DP_VIEWZOOM. */ +#endif +#if defined(CSQC) || defined(SSQC) +const float STAT_USER = 32; /* Custom user stats start here (lower values are reserved for engine use). */ +#endif +#if defined(CSQC) || defined(MENU) +const float PRECACHE_PIC_FROMWAD = 1; /* Attempt to load it from the legacy gfx.wad file (usually its better to just use a gfx/ prefix instead). */ +const float PRECACHE_PIC_NOCLAMP = 4; /* Texture coords for the pic will not be clamped nor padded nor atlased. */ +const float PRECACHE_PIC_DOWNLOAD = 256; /* If no image could be loaded then attempt to download one from the server. This flag can cause the function to block until completion. (Slow!) */ +const float PRECACHE_PIC_TEST = 512; /* The precache will block until the image is fully loaded, returning a null string on failure. (Slow!) */ +const float VF_MIN = 1; /* The top-left of the 3d viewport in screenspace. The VF_ values are used via the setviewprop/getviewprop builtins. */ +const float VF_MIN_X = 2; +const float VF_MIN_Y = 3; +const float VF_SIZE = 4; /* The width+height of the 3d viewport in screenspace. */ +const float VF_SIZE_X = 5; +const float VF_SIZE_Y = 6; +const float VF_VIEWPORT = 7; /* vector+vector. Two argument shortcut for VF_MIN and VF_SIZE */ +const float VF_FOV = 8; /* sets both fovx and fovy. consider using afov instead. */ +const float VF_FOV_X = 9; /* horizontal field of view. does not consider aspect at all. */ +const float VF_FOV_Y = 10; /* vertical field of view. does not consider aspect at all. */ +const float VF_ORIGIN = 11; /* The origin of the view. Not of the player. */ +const float VF_ORIGIN_X = 12; +const float VF_ORIGIN_Y = 13; +const float VF_ORIGIN_Z = 14; +const float VF_ANGLES = 15; /* The angles the view will be drawn at. Not the angle the client reports to the server. */ +const float VF_ANGLES_X = 16; +const float VF_ANGLES_Y = 17; +const float VF_ANGLES_Z = 18; +#endif +#ifdef CSQC +const float VF_DRAWWORLD = 19; /* boolean. If set to 1, the engine will draw the world and static/persistant rtlights. If 0, the world will be skipped and everything will be fullbright. */ +const float VF_DRAWENGINESBAR = 20; /* boolean. If set to 1, the sbar will be drawn, and viewsize will be honoured automatically. */ +const float VF_DRAWCROSSHAIR = 21; /* boolean. If set to 1, the engine will draw its default crosshair. */ +#endif +#if defined(CSQC) || defined(MENU) +const float VF_MINDIST = 23; /* The distance of the near clip plane from the view position. Should generally not be <=0, as this would introduce NANs. */ +const float VF_MAXDIST = 24; /* The distance of the far clip plane from the view position. If 0, will be considered infinite. */ +#endif +#ifdef CSQC +const float VF_CL_VIEWANGLES = 33; +const float VF_CL_VIEWANGLES_X = 34; +const float VF_CL_VIEWANGLES_Y = 35; +const float VF_CL_VIEWANGLES_Z = 36; +#endif +#if defined(CSQC) || defined(MENU) +const float VF_PERSPECTIVE = 200; /* 1: regular rendering. Fov specifies the angle. 0: isometric-style. Fov specifies the number of Quake Units each side of the viewport, and mindist restrictions are removed, pvs culling should be disabled. */ +#endif +#ifdef CSQC +#define VF_LPLAYER VF_ACTIVESEAT +const float VF_ACTIVESEAT = 202; /* The 'seat' number, used when running splitscreen. */ +#endif +#if defined(CSQC) || defined(MENU) +const float VF_AFOV = 203; /* Aproximate fov. Matches the 'fov' cvar. The engine handles the aspect ratio for you. */ +const float VF_SCREENVSIZE = 204; /* Provides a reliable way to retrieve the current virtual screen size (even if the screen is automatically scaled to retain aspect). */ +const float VF_SCREENPSIZE = 205; /* Provides a reliable way to retrieve the current physical screen size (cvars need vid_restart for them to take effect). */ +#endif +#ifdef CSQC +const float VF_VIEWENTITY = 206; /* Changes the RF_EXTERNALMODEL flag on entities to match the new selection, and removes entities flaged with RF_VIEWENTITY. Requires cunning use of .entnum and typically requires calling addentities(MASK_VIEWMODEL) too. */ +#endif +#if defined(CSQC) || defined(MENU) +const float VF_RT_DESTCOLOUR = 212; /* The texture name to write colour info into, this includes both 3d and 2d drawing. +Additional arguments are: format (IMGFMT_*), sizexy. +Written to by both 3d and 2d rendering. +Note that any rendertarget textures may be destroyed on video mode changes or so. Shaders can name render targets by prefixing texture names with '$rt:', or $sourcecolour. */ +const float VF_RT_DESTCOLOUR1 = 213; /* Like VF_RT_DESTCOLOUR, for multiple render targets. */ +const float VF_RT_DESTCOLOUR2 = 214; /* Like VF_RT_DESTCOLOUR, for multiple render targets. */ +const float VF_RT_DESTCOLOUR3 = 215; /* Like VF_RT_DESTCOLOUR, for multiple render targets. */ +const float VF_RT_SOURCECOLOUR = 209; /* The texture name to use with shaders that specify a $sourcecolour map. */ +const float VF_RT_DEPTH = 210; /* The texture name to use as a depth buffer. Also used for shaders that specify $sourcedepth. 1-based. Additional arguments are: format (IMGFMT_D*), sizexy. */ +const float VF_RT_RIPPLE = 211; /* The texture name to use as a ripplemap (target for shaders with 'sort ripple'). Also used for shaders that specify $ripplemap. 1-based. Additional arguments are: format, sizexy. */ +const float VF_ENVMAP = 220; /* The cubemap name to use as a fallback for $reflectcube, if a shader was unable to load one. Note that this doesn't automatically change shader permutations or anything. */ +const float VF_USERDATA = 221; /* Pointer (and byte size) to an array of vec4s. This data is then globally visible to all glsl via the w_user uniform. */ +#endif +#ifdef CSQC +const float VF_SKYROOM_CAMERA = 222; /* Controls the camera position of the skyroom (which will be drawn underneath transparent sky surfaces). This should move slightly with the real camera, but not so much that the skycamera enters walls. Requires a skyshader with a blend mode on the first pass (or no passes). */ +#endif +#if defined(CSQC) || defined(MENU) +const float VF_PROJECTIONOFFSET = 224; /* vec2 horizontal+vertical offset for the projection matrix, for weird off-centre rendering. */ +const float DRAWFLAG_NORMAL = 0; /* Args for drawpic/drawfill/beginpolygon. Not to be confused with the hexen2-compatibility feature. */ +const float DRAWFLAG_ADD = 1; /* Forces additive blending, overriding any shader settings. */ +const float DRAWFLAG_MODULATE = 2; /* Forces alpha blending, overriding any shader settings. */ +const float DRAWFLAG_2D = 4; /* For use with beginpolygon. The polygon will be drawn to the 2d screen, instead of being added to the 3d scene. */ +const float DRAWFLAG_TWOSIDED = 1024; /* For use with beginpolygon. The polygon will be two-sided without any backface culling. */ +const float DRAWFLAG_LINES = 2048; /* For use with beginpolygon. The surface verticies should be interpreted as a line loop, instead of a triangle fan. */ +const float IMGFMT_R8G8B8A8 = 1; /* Typical 32bit rgba pixel format. */ +const float IMGFMT_R16G16B16A16F = 2; /* Half-Float pixel format. Requires gl3 support. */ +const float IMGFMT_R32G32B32A32F = 3; /* Regular Float pixel format. Requires gl3 support. */ +const float IMGFMT_D16 = 4; /* 16-bit depth pixel format. Must not be used with VF_RT_DESTCOLOUR*. */ +const float IMGFMT_D24 = 5; /* 24-bit depth pixel format. Must not be used with VF_RT_DESTCOLOUR*. */ +const float IMGFMT_D32 = 6; /* 32-bit depth pixel format. Must not be used with VF_RT_DESTCOLOUR*. */ +const float IMGFMT_R8 = 7; /* Single channel red-only 8bit pixel format. */ +const float IMGFMT_R16F = 8; /* Single channel red-only Half-Float pixel format. Requires gl3 support. */ +const float IMGFMT_R32F = 9; /* Single channel red-only Float pixel format. Requires gl3 support. */ +const float IMGFMT_A2B10G10R10 = 10; /* Packed 32-bit packed 10-bit colour pixel format. Requires gl3 support. */ +const float IMGFMT_R5G6B5 = 11; /* Packed 16-bit colour pixel format. */ +const float IMGFMT_R4G4B4A4 = 12; /* Packed 16-bit colour pixel format, with alpha */ +const float IMGFMT_R8G8 = 13; /* 16-bit two-channel pixel format. */ +const float IMGFMT_R32G32B32F = 14; /* A pixel format that matches QC's vector type. */ +#endif +#ifdef CSQC +const float RF_VIEWMODEL = 1; /* Specifies that the entity is a view model, and that its origin is relative to the current view position. These entities are also subject to viewweapon bob. */ +const float RF_EXTERNALMODEL = 2; /* Specifies that this entity should be displayed in mirrors (and may still cast shadows), but will not otherwise be visible. */ +#endif +#if defined(CSQC) || defined(MENU) +const float RF_DEPTHHACK = 4; /* Hacks the depth values such that the entity uses depth values as if it were closer to the screen. This is useful when combined with viewmodels to avoid weapons poking in to walls. */ +const float RF_ADDITIVE = 8; /* Shaders from this entity will temporarily be hacked to use an additive blend mode instead of their normal blend mode. */ +#endif +#ifdef CSQC +const float RF_USEAXIS = 16; /* The entity will be oriented according to the current v_forward+v_right+v_up vector values instead of the entity's .angles field. */ +const float RF_NOSHADOW = 32; /* This entity will not cast shadows. Often useful on view models. */ +const float RF_FRAMETIMESARESTARTTIMES = 64; /* Specifies that the frame1time, frame2time field are timestamps (denoting the start of the animation) rather than time into the animation. */ +const float RF_FIRSTPERSON = 1024; /* This is basically the opposite of RF_EXTERNALMODEL. Don't draw in third-person or mirrors. */ +#endif +#if defined(CSQC) || defined(MENU) +const float IE_KEYDOWN = 0; /* Specifies that a key was pressed. Second argument is the scan code. Third argument is the unicode (printable) char value. Fourth argument denotes which keyboard(or mouse, if its a mouse 'scan' key) the event came from. Note that some systems may completely separate scan codes and unicode values, with a 0 value for the unspecified argument. */ +const float IE_KEYUP = 1; /* Specifies that a key was released. Arguments are the same as IE_KEYDOWN. On some systems, this may be fired instantly after IE_KEYDOWN was fired. */ +const float IE_MOUSEDELTA = 2; /* Specifies that a mouse was moved (touch screens and tablets typically give IE_MOUSEABS events instead, use in_windowed_mouse 0 to test code to cope with either). Second argument is the X displacement, third argument is the Y displacement. Fourth argument is which mouse or touch event triggered the event. */ +const float IE_MOUSEABS = 3; /* Specifies that a mouse cursor or touch event was moved to a specific location relative to the virtual screen space. Second argument is the new X position, third argument is the new Y position. Fourth argument is which mouse or touch event triggered the event. */ +const float IE_ACCELEROMETER = 4; +const float IE_FOCUS = 5; /* Specifies that input focus was given. parama says mouse focus, paramb says keyboard focus. If either are -1, then it is unchanged. */ +const float IE_JOYAXIS = 6; /* Specifies that what value a joystick/controller axis currently specifies. x=axis, y=value. Will be called multiple times, once for each axis of each active controller. */ +const float IE_GYROSCOPE = 7; +const float GGDI_GAMEDIR = 0; /* Used with getgamedirinfo to query the mod's public gamedir. There is often other info that cannot be expressed with just a gamedir name, resulting in dupes or other weirdness. */ +const float GGDI_DESCRIPTION = 1; /* The human-readable title of the mod. Empty when no data is known (ie: the gamedir just contains some maps). */ +const float GGDI_OVERRIDES = 2; /* A list of settings overrides. */ +const float GGDI_LOADCOMMAND = 3; /* The console command needed to actually load the mod. */ +const float GGDI_ICON = 4; /* The mod's Icon path, ready for drawpic. */ +const float GGDI_GAMEDIRLIST = 5; /* A semi-colon delimited list of gamedirs that the mod's content can be loaded through. */ +#endif +#ifdef SSQC +const float CLIENTTYPE_DISCONNECTED = 0; /* Return value from clienttype() builtin. This entity is a player slot that is currently empty. */ +const float CLIENTTYPE_REAL = 1; /* This is a real player, and not a bot. */ +const float CLIENTTYPE_BOT = 2; /* This player slot does not correlate to a real player, any messages sent to this client will be ignored. */ +const float CLIENTTYPE_NOTACLIENT = 3; /* This entity is not even a player slot. This is typically an error condition. */ +#endif +const float FILE_READ = 0; /* The file may be read via fgets to read a single line at a time. */ +const float FILE_APPEND = 1; /* Like FILE_WRITE, but writing starts at the end of the file. */ +const float FILE_WRITE = 2; /* fputs will be used to write to the file. */ +const float FILE_READNL = 4; /* Like FILE_READ, except newlines are not special. fgets reads the entire file into a tempstring. */ +const float FILE_MMAP_READ = 5; /* The file will be loaded into memory. fgets returns a pointer to the first byte (and will always return the same value for this file). Cast this to your datatype. */ +const float FILE_MMAP_RW = 6; /* Like FILE_MMAP_READ, except any changes to the data will be written back to disk once the file is closed. */ +#ifdef CSQC +const float MASK_ENGINE = 1; /* Valid as an argument for addentities. If specified, all non-csqc entities will be added to the scene. */ +const float MASK_VIEWMODEL = 2; /* Valid as an argument for addentities. If specified, the regular engine viewmodel will be added to the scene. */ +const float PREDRAW_AUTOADD = 0; /* Valid as a return value from the predraw function. Returning this will cause the engine to automatically invoke addentity(self) for you. */ +const float PREDRAW_NEXT = 1; /* Valid as a return value from the predraw function. Returning this will simply move on to the next entity without the autoadd behaviour, so can be used for particle/invisible/special entites, or entities that were explicitly drawn with addentity. */ +const float LFIELD_ORIGIN = 0; +const float LFIELD_COLOUR = 1; +const float LFIELD_RADIUS = 2; +const float LFIELD_FLAGS = 3; +const float LFIELD_STYLE = 4; +const float LFIELD_ANGLES = 5; +const float LFIELD_FOV = 6; +const float LFIELD_CORONA = 7; +const float LFIELD_CORONASCALE = 8; +const float LFIELD_CUBEMAPNAME = 9; +const float LFIELD_AMBIENTSCALE = 10; +const float LFIELD_DIFFUSESCALE = 11; +const float LFIELD_SPECULARSCALE = 12; +const float LFIELD_ROTATION = 13; +const float LFIELD_DIETIME = 14; +const float LFIELD_RGBDECAY = 15; +const float LFIELD_RADIUSDECAY = 16; +const float LFIELD_STYLESTRING = 17; +const float LFIELD_NEARCLIP = 18; +const float LFIELD_OWNER = 19; +const float LFLAG_NORMALMODE = 1; +const float LFLAG_REALTIMEMODE = 2; +const float LFLAG_LIGHTMAP = 4; +const float LFLAG_FLASHBLEND = 8; +const float LFLAG_NOSHADOWS = 256; +const float LFLAG_SHADOWMAP = 512; +const float LFLAG_CREPUSCULAR = 1024; +const float LFLAG_ORTHOSUN = 2048; +const float TEREDIT_RELOAD = 0; +const float TEREDIT_SAVE = 1; +const float TEREDIT_SETHOLE = 2; +const float TEREDIT_HEIGHT_SET = 3; +const float TEREDIT_HEIGHT_SMOOTH = 4; +const float TEREDIT_HEIGHT_SPREAD = 5; +const float TEREDIT_HEIGHT_RAISE = 6; +const float TEREDIT_HEIGHT_FLATTEN = 18; +const float TEREDIT_HEIGHT_LOWER = 7; +const float TEREDIT_TEX_KILL = 8; +const float TEREDIT_TEX_GET = 9; +const float TEREDIT_TEX_BLEND = 10; +const float TEREDIT_TEX_UNIFY = 11; +const float TEREDIT_TEX_NOISE = 12; +const float TEREDIT_TEX_BLUR = 13; +const float TEREDIT_TEX_REPLACE = 19; +const float TEREDIT_TEX_SETMASK = 25; +const float TEREDIT_WATER_SET = 14; +const float TEREDIT_MESH_ADD = 15; +const float TEREDIT_MESH_KILL = 16; +const float TEREDIT_TINT = 17; +const float TEREDIT_RESET_SECT = 20; +const float TEREDIT_RELOAD_SECT = 21; +const float TEREDIT_ENT_GET = 26; +const float TEREDIT_ENT_SET = 27; +const float TEREDIT_ENT_ADD = 28; +const float TEREDIT_ENT_COUNT = 29; +#endif +#if defined(CSQC) || defined(MENU) +const float SLIST_HOSTCACHEVIEWCOUNT = 0; +const float SLIST_HOSTCACHETOTALCOUNT = 1; +const float SLIST_MASTERQUERYCOUNT = 2; +const float SLIST_MASTERREPLYCOUNT = 3; +const float SLIST_SERVERQUERYCOUNT = 4; +const float SLIST_SERVERREPLYCOUNT = 5; +const float SLIST_SORTFIELD = 6; +const float SLIST_SORTDESCENDING = 7; +const float SLIST_TEST_CONTAINS = 0; +const float SLIST_TEST_NOTCONTAIN = 1; +const float SLIST_TEST_LESSEQUAL = 2; +const float SLIST_TEST_LESS = 3; +const float SLIST_TEST_EQUAL = 4; +const float SLIST_TEST_GREATER = 5; +const float SLIST_TEST_GREATEREQUAL = 6; +const float SLIST_TEST_NOTEQUAL = 7; +const float SLIST_TEST_STARTSWITH = 8; +const float SLIST_TEST_NOTSTARTSWITH = 9; +#endif +#ifdef MENU +float(string ext) checkextension = #1; /* + Checks if the named extension is supported by the running engine. */ + +void(string err,...) error = #2; /* + Fatal error that will trigger a crash-to-console that users will actually notice. */ + +void(string err,...) objerror = #3; /* + For some reason this has been redefined as non-fatal, and as it won't force the user to look at the console it'll generally be ignored completely so really what's the point? Other than as a convoluted way to remove(self) that is. */ + +void(string text,...) print = #4; /* Part of DP_SV_PRINT + Hello, world. Shoves junk on the console. Hopefully people will bother to read it, maybe. */ + +DEP void(string text,...) bprint = #5; +DEP void(float clientnum, string text,...) msprint = #6; +void(string text,...) cprint = #7; /* + Tries to show the given message in the centre of the screen, assuming that its not obscured by menus. Oh hey look, you're calling it in menuqc! */ + +vector(vector) normalize = #8; +float(vector) vlen = #9; +float(vector) vectoyaw = #10; +vector(vector) vectoangles = #11; +float() random = #12; +void(string,...) localcmd = #13; +float(string name) cvar = #14; +void(string name, string value) cvar_set = #15; +void(string text, ...) dprint = #16; +string(float) ftos = #17; +float(float) fabs = #18; +string(vector) vtos = #19; +string(entity) etos = #20; /* Part of DP_QC_ETOS*/ +float(string) stof = #21; /* Part of FRIK_FILE, FTE_QC_INFOKEY, FTE_STRINGS, QW_ENGINE, ZQ_QC_STRINGS*/ +entity() spawn = #22; +void(entity) remove = #23; +entity(entity start, .string field, string match) find = #24; +entity(entity start, .__variant field, __variant match) findfloat = #25; /* Part of DP_QC_FINDFLOAT*/ +entity(.string field, string match) findchain = #26; /* Part of DP_QC_FINDCHAIN*/ +entity(.__variant field, __variant match) findchainfloat = #27; /* Part of DP_QC_FINDCHAINFLOAT*/ +string(string file) precache_file = #28; /* + Attempts to download the named file from the current server, if it isn't found locally. Not very useful as menuqc is normally meant to work before joining servers too. */ + +string(string sample) precache_sound = #29; +void() coredump = #30; /* + Takes a dump, writing the qcvm's state to disk. There are normally easier ways to debug, but I suppose this one still beats print spam. */ + +void() traceon = #31; /* + Enables single-stepping. Its generally easier to just set a breakpoint. */ + +void() traceoff = #32; /* + Disables single-stepping. Which sucks if you started said singlestepping outside of qc. */ + +void(entity) eprint = #33; +float(float) rint = #34; +float(float) floor = #35; +float(float) ceil = #36; +entity(entity) nextent = #37; +float(float) sin = #38; /* Part of DP_QC_SINCOSSQRTPOW*/ +float(float) cos = #39; /* Part of DP_QC_SINCOSSQRTPOW*/ +float(float) sqrt = #40; /* Part of DP_QC_SINCOSSQRTPOW*/ +vector() randomvector = #41; +float(string name, string value, float flags) registercvar = #42; /* Part of DP_REGISTERCVAR + Creates the cvar if it didn't already exist. This presents issues for setting those cvars via startup configs of course, and autocvars are easier but I suppose they don't get any flags (which are ignored anyway, of course). */ + +float(float,...) min = #43; /* Part of DP_QC_MINMAXBOUND*/ +float(float,...) max = #44; /* Part of DP_QC_MINMAXBOUND*/ +float(float min,float value,float max) bound = #45; /* Part of DP_QC_MINMAXBOUND*/ +float(float,float) pow = #46; /* Part of DP_QC_SINCOSSQRTPOW*/ +void(entity src, entity dst) copyentity = #47; /* Part of DP_QC_COPYENTITY + Copies all entity fields from one entity into another (forgetting any that were previously set on the destination). */ + +filestream(string filename, float mode) fopen = #48; /* Part of FRIK_FILE*/ +void(filestream fhandle) fclose = #49; /* Part of FRIK_FILE*/ +string(filestream fhandle) fgets = #50; /* Part of FRIK_FILE*/ +void(filestream fhandle, string s) fputs = #51; /* Part of FRIK_FILE*/ +float(string) strlen = #52; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ +string(string, optional string, optional string, optional string, optional string, optional string, optional string, optional string) strcat = #53; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ +string(string s, float start, float length) substring = #54; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ +vector(string) stov = #55; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ +FTEDEP("Redundant") string(string) strzone = #56; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS + Exists in FTE for compat only, no different from strcat. */ + +FTEDEP("Redundant") void(string) strunzone = #57; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS + Exists in FTE for compat only, does nothing. */ + +float(string) tokenize = #58; /* Part of KRIMZON_SV_PARSECLIENTCOMMAND + Splits up the given string into its different components (what constitutes a token separator is not well defined and has been hacked about with over the years so have fun with that), returning the number of tokens that were found. Call argv(0 through ret-1) to retrieve each individual token. Take care to not use this recursively. */ + +string(float) argv = #59; /* Part of KRIMZON_SV_PARSECLIENTCOMMAND + Returns one of the tokens found via tokenize (and equivelent builtins). */ + +float() isserver = #60; /* + Returns true if the local engine is running a server, and thus cvars and localcmds are shared with said server. */ + +float() clientcount = #61; /* + Returns the maximum number of players on the server. Useless if its a remote server, so its a kinda useless builtin really. */ + +float() clientstate = #62; /* + Tells you whether the client is actually connected to anything. 0 for a dedicated server (but dedicated servers don't normally run menuqc anyway), 2 if connecting or connected to a server (but not necessarily spawned+active), 1 for sitting around idle without trying to connect to anything yet. */ + +void(string map) changelevel = #64; /* + Not really any different from a localcmd, but with proper string escapes. */ + +void(string sample, optional float channel, optional float volume) localsound = #65; /* + Plays a sound, locally. precaching is optional, but recommended. */ + +vector() getmousepos = #66; /* + Obsolete. Return values depend upon the current cursor mode. Implement Menu_InputEvent instead, so you can handle deltas as-is or absolutes if that's all the OS can provide. */ + +float(optional float timetype) gettime = #67; +void(string s) loadfromdata = #68; /* + Reads a set of entities from the given string. This string should have the same format as a .ent file or a saved game. Entities will be spawned as required. If you need to see the entities that were created, you should use parseentitydata instead. */ + +void(string s) loadfromfile = #69; /* + Reads a set of entities from the named file. This file should have the same format as a .ent file or a saved game. Entities will be spawned as required. If you need to see the entities that were created, you should use parseentitydata instead. */ + +float(float val, float m) mod = #70; +string(string name) cvar_string = #71; /* Part of DP_QC_CVAR_STRING + Returns the value of a cvar, as a string. */ + +FTEDEP("Call 'error' instead") void() crash = #72; /* + Demonstrates that no program is bug free. */ + +void() stackdump = #73; /* + Prints out the QC's stack, for console-based error reports. */ + +searchhandle(string pattern, enumflags:float{SB_CASEINSENSITIVE=1<<0,SB_FULLPACKAGEPATH=1<<1,SB_ALLOWDUPES=1<<2,SB_FORCESEARCH=1<<3,SB_MULTISEARCH=1<<4,SB_NAMESORT=1<<5} flags, float quiet, optional string package) search_begin = #74; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE*/ +void(searchhandle handle) search_end = #75; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE*/ +float(searchhandle handle) search_getsize = #76; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE*/ +string(searchhandle handle, float num) search_getfilename = #77; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE*/ +float(entity) etof = #79; +entity(float) ftoe = #80; +float(string) validstring = #81; /* + Returns true if str isn't null. In case 'if [not](str)' was configured to test for empty instead of null. */ + +DEP float(string str) altstr_count = #82; /* + Reports how many single-quotes there were in the string, divided by 2. */ + +DEP string(string str) altstr_prepare = #83; /* + Adds markup to escape only single-quotes. Does not add any. */ + +DEP string(string str, float num) altstr_get = #84; /* + Gets the Nth single-quoted token in the input. */ + +DEP string(string str, float num, string setval) altstr_set = #85; /* + Changes the Nth single-quoted token. The setval argument must not contain any single-quotes (use altstr_prepare to ensure this). */ + +entity(entity start, .float field, float match) findflags = #87; /* Part of DP_QC_FINDFLAGS*/ +entity(.float field, float match) findchainflags = #88; /* Part of DP_QC_FINDCHAINFLAGS*/ +string(string name) cvar_defstring = #89; /* Part of DP_QC_CVAR_DEFSTRING*/ +void(entity ent, string mname) setmodel = #90; /* + Menuqc-specific version. */ + +void(string mname) precache_model = #91; /* + Menuqc-specific version. */ + +void(entity ent, vector neworg) setorigin = #92; /* + Menuqc-specific version. */ + +#endif +#if defined(CSQC) || defined(SSQC) +void(vector vang) makevectors = #1; /* + Takes an angle vector (pitch,yaw,roll) (+x=DOWN). Writes its results into v_forward, v_right, v_up vectors. */ + +void(entity e, vector o) setorigin = #2; /* + Changes e's origin to be equal to o. Also relinks collision state (as well as setting absmin+absmax), which is required after changing .solid */ + +void(entity e, string m) setmodel = #3; /* + Looks up m in the model precache list, and sets both e.model and e.modelindex to match. BSP models will set e.mins and e.maxs accordingly, other models depend upon the value of sv_gameplayfix_setmodelrealbox - for compatibility you should always call setsize after all pickups or non-bsp models. Also relinks collision state. */ + +void(entity e, vector min, vector max) setsize = #4; /* + Sets the e's mins and maxs fields. Also relinks collision state, which sets absmin and absmax too. */ + +void() breakpoint = #6; /* + Trigger a debugging event. FTE will break into the qc debugger. Other engines may crash with a debug execption. */ + +float() random = #7; /* + Returns a random value between 0 and 1. Be warned, this builtin can return 1 in most engines, which can break arrays. */ + +void(entity e, float chan, string samp, float vol, float atten, optional float speedpct, optional float flags, optional float timeofs) sound = #8; /* + Starts a sound centered upon the given entity. + chan is the entity sound channel to use, channel 0 will allow you to mix many samples at once, others will replace the old sample + 'samp' must have been precached first + if specified, 'speedpct' should normally be around 100 (or =0), 200 for double speed or 50 for half speed. + If flags is specified, the reliable flag in the channels argument is used for additional channels. Flags should be made from SOUNDFLAG_* constants + timeofs should be negative in order to provide a delay before the sound actually starts. */ + +vector(vector v) normalize = #9; /* + Shorten or lengthen a direction vector such that it is only one quake unit long. */ + +void(string e) error = #10; /* + Ends the game with an easily readable error message. */ + +void(string e) objerror = #11; /* + Displays a non-fatal easily readable error message concerning the self entity, including a field dump. self will be removed! */ + +float(vector v) vlen = #12; /* + Returns the square root of the dotproduct of a vector with itself. Or in other words the length of a distance vector, in quake units. */ + +float(vector v, optional entity reference) vectoyaw = #13; /* + Given a direction vector, returns the yaw angle in which that direction vector points. If an entity is passed, the yaw angle will be relative to that entity's gravity direction. */ + +entity() spawn = #14; /* + Adds a brand new entity into the world! Hurrah, you're now a parent! */ + +void(entity e) remove = #15; /* + Destroys the given entity and clears some limited fields (including model, modelindex, solid, classname). Any references to the entity following the call are an error. After half a second the entity will be reused, in the interim you can unfortunatly still read its fields to see if the reference is no longer valid. */ + +#endif +void(entity e) removeinstant = #0:removeinstant; /* + Same thing as the regular remove builtin, but bypasses the half-second rule. The entity slot may be reused instantly. Be CERTAIN that you have no lingering references, because if they're followed they will end up poking an entirely different type of entity! So only use this where you're sure its safe. */ + +#if defined(CSQC) || defined(SSQC) +void(vector v1, vector v2, float flags, entity ent) traceline = #16; /* + Traces a thin line through the world from v1 towards v2. + Will not collide with ent, ent.owner, or any entity who's owner field refers to ent. + The passed entity will also be used to determine whether to use a capsule trace, the contents that the trace should impact, and a couple of other extra fields that define the trace. + There are no side effects beyond the trace_* globals being written. + flags&MOVE_NOMONSTERS will not impact on non-bsp entities. + flags&MOVE_MISSILE will impact with increased size. + flags&MOVE_HITMODEL will impact upon model meshes, instead of their bounding boxes. + flags&MOVE_TRIGGERS will also stop on triggers + flags&MOVE_EVERYTHING will stop if it hits anything, even non-solid entities. + flags&MOVE_LAGGED will backdate entity positions for the purposes of this builtin according to the indicated player ent's latency, to provide lag compensation. */ + +#endif +#ifdef SSQC +entity() checkclient = #17; /* + Returns one of the player entities. The returned player will change periodically. */ + +#endif +#if defined(CSQC) || defined(SSQC) +entity(entity start, .string fld, string match) find = #18; /* + Scan for the next entity with a given field set to the given 'match' value. start should be either world, or the previous entity that was found. Returns world on failure/if there are no more. + If you have many many entities then you may find that hashtables will give more performance (but requires extra upkeep). */ + +#endif +entity*(.__variant fld, __variant match, int type=EV_STRING, __out int count) find_list = #0:find_list; /* + Scan for the next entity with a given field set to the given 'match' value. start should be either world, or the previous entity that was found. Returns world on failure/if there are no more. + If you have many many entities then you may find that hashtables will give more performance (but requires extra upkeep). */ + +#if defined(CSQC) || defined(SSQC) +string(string s) precache_sound = #19; /* + Precaches a sound, making it known to clients and loading it from disk. This builtin (strongly) should be called during spawn functions. This builtin must be called for the sound before the sound builtin is called, or it might not even be heard. */ + +string(string s) precache_model = #20; /* + Precaches a model, making it known to clients and loading it from disk if it has a .bsp extension. This builtin (strongly) should be called during spawn functions. This must be called for each model name before setmodel may use that model name. + Modelindicies precached in SSQC will always be positive. CSQC precaches will be negative if they are not also on the server. */ + +#endif +#ifdef SSQC +void(entity client, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7) stuffcmd = #21; /* + Sends a console command (or cvar) to the client, where it will be executed. Different clients support different commands. Do NOT forget the final \n. + This builtin is generally considered evil. */ + +void(entity client, float flags, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6) stuffcmdflags = #0:stuffcmdflags; /* Part of FTE_QC_STUFFCMDFLAGS + Sends a console command (or cvar) to the client, where it will be executed. Different clients support different commands. Do NOT forget the final \n. + This (just as evil) variant allows specifying some flags too. See the STUFFCMD_* constants. */ + +#endif +#if defined(CSQC) || defined(SSQC) +entity(vector org, float rad, optional .entity chainfield) findradius = #22; /* + Finds all entities within a distance of the 'org' specified. One entity is returned directly, while other entities are returned via that entity's .chain field. Use findradius_list for an updated alternative without reenterancy issues. */ + +entity*(vector org, float rad, __out int foundcount, int sort=0) findradius_list = #0:findradius_list; /* + Finds all entities linked with a bbox within a distance of the 'org' specified, returning the list as a temp-array (world signifies the end). Unlike findradius, sv_gameplayfix_blowupfallenzombies is ignored (use FL_FINDABLE_NONSOLID instead), while sv_gameplayfix_findradiusdistancetobox and dpcompat_findradiusarealinks are force-enabled. The resulting buffer will automatically be cleaned up by the engine and does not need to be freed. */ + +#endif +#if defined(NQSSQC) +void(string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7, optional string s8) bprint = #23; /* + NQ: Concatenates all arguments, and prints the messsage on the console of all connected clients. */ + +#endif +#if defined(QWSSQC) +void(float msglvl, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7) bprint = #23; /* + QW: Concatenates all string arguments, and prints the messsage on the console of only all clients who's 'msg' infokey is set lower or equal to the supplied 'msglvl' argument. */ + +#endif +#if defined(NQSSQC) +void(entity client, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7) sprint = #24; /* + NQ: Concatenates all string arguments, and prints the messsage on the named client's console */ + +#endif +#if defined(QWSSQC) +void(entity client, float msglvl, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6) sprint = #24; /* + QW: Concatenates all string arguments, and prints the messsage on the named client's console, but only if that client's 'msg' infokey is set lower or equal to the supplied 'msglvl' argument. */ + +#endif +#if defined(CSQC) || defined(NQSSQC) +void(string s, ...) dprint = #25; /* + NQ: Prints the given message on the server's console, but only if the developer cvar is set. Arguments will be concatenated into a single message. */ + +#endif +#if defined(CSQC) || defined(QWSSQC) +void(string s, ...) dprint = #25; /* + QW: Unconditionally prints the given message on the server's console. Arguments will be concatenated into a single message. */ + +#endif +#if defined(CSQC) || defined(SSQC) +string(float val) ftos = #26; /* + Returns a tempstring containing a representation of the given float. Precision depends upon engine. */ + +string(vector val) vtos = #27; /* + Returns a tempstring containing a representation of the given vector. Precision depends upon engine. */ + +void() coredump = #28; /* + Writes out a coredump. This contains stack, globals, and field info for all ents. This can be handy for debugging. */ + +void() traceon = #29; /* + Enables tracing. This may be spammy, slow, and stuff. Set debugger 1 in order to use fte's qc debugger. */ + +void() traceoff = #30; /* + Disables tracing again. */ + +void(entity e) eprint = #31; /* + Debugging builtin that prints all fields of the given entity to the console. */ + +float(float yaw, float dist, optional float settraceglobals) walkmove = #32; /* + Attempt to walk the entity at a given angle for a given distance. + if settraceglobals is set, the trace_* globals will be set, showing the results of the movement. + This function will trigger touch events. */ + +float() droptofloor = #34; /* + Instantly moves the entity downwards until it hits the ground. If the entity is in solid or would need to drop more than 'pr_droptofloorunits' quake units, its position will be considered invalid and the builtin will abort, returning FALSE, otherwise TRUE. */ + +void(float lightstyle, string stylestring, optional vector rgb) lightstyle = #35; /* + Specifies an auto-animating string that specifies the light intensity for entities using that lightstyle. + a is off, z is fully lit. Should be lower case only. + rgb will recolour all lights using that lightstyle. */ + +float(float) rint = #36; /* + Rounds the given float up or down to the closest integeral value. X.5 rounds away from 0 */ + +float(float) floor = #37; /* + Rounds the given float downwards, even when negative. */ + +float(float) ceil = #38; /* + Rounds the given float upwards, even when negative. */ + +float(entity ent) checkbottom = #40; /* + Expensive checks to ensure that the entity is actually sitting on something solid, returns true if it is. */ + +float(vector pos) pointcontents = #41; /* + Checks the given point to see what is there. Returns one of the CONTENTS_* constants. Just because a point is empty does not mean that the player can stand there due to the size of the player - use tracebox for such tests. */ + +__uint(vector pos, optional float worldonly=1) pointcontentsmask = #0:pointcontentsmask; /* + Checks the given point to see what is there. Returns a mask of the CONTENTBIT_* constants. Just because a point is empty does not mean that the player can stand there due to the size of the player - use tracebox for such tests. */ + +float(float) fabs = #43; /* + Removes the sign of the float, making it positive if it is negative. */ + +#endif +#ifdef SSQC +vector(entity player, float missilespeed) aim = #44; /* + Returns a tweaked copy of the v_forward vector (must be set! ie: makevectors(player.v_angle) ). This is important for keyboard users (that don't want to have to look up/down the whole time), as well as joystick users (who's aim is otherwise annoyingly imprecise). Only the upwards component of the result will differ from the value of v_forward. The builtin will select the enemy closest to the crosshair within the angle of acos(sv_aim). */ + +#endif +#if defined(CSQC) || defined(SSQC) +float(string) cvar = #45; /* + Returns the numeric value of the named cvar */ + +void(string, ...) localcmd = #46; /* + Adds the string to the console command queue. Commands will not be executed immediately, but rather at the start of the following frame. */ + +entity(entity) nextent = #47; /* + Returns the following entity. Skips over removed entities. Returns world when passed the last valid entity. */ + +void(vector pos, vector dir, float colour, float count) particle = #48; /* + Spawn 'count' particles around 'pos' moving in the direction 'dir', with a palette colour index between 'colour' and 'colour+8'. */ + +#define ChangeYaw changeyaw +void() changeyaw = #49; /* + Changes the self.angles_y field towards self.ideal_yaw by up to self.yaw_speed. */ + +vector(vector fwd, optional vector up) vectoangles = #51; /* + Returns the angles (+x=UP) required to orient an entity to look in the given direction. The 'up' argument is required if you wish to set a roll angle, otherwise it will be limited to just monster-style turning. */ + +#endif +#ifdef SSQC +void(float to, float val) WriteByte = #52; /* + Writes a single byte into a network message buffer. Typically you will find a more correct alternative to writing arbitary data. 'to' should be one of the MSG_* constants. MSG_ONE must have msg_entity set first. */ + +void(float to, float val) WriteChar = #53; /* + Writes a signed value between -128 and 127. */ + +void(float to, float val) WriteShort = #54; /* + Writes a signed value between -32768 and 32767. As an exception, values up to 65535 will not trigger warnings (but readshort will read the result as negative!) */ + +void(float to, float val) WriteLong = #55; /* + Writes a signed 32bit integer. Note that the input argument being of float type limits the resulting integer to a mere 24 consecutive bits of validity. Use WriteInt if you want to write an entire 32bit int without data loss. */ + +void(float to, float val) WriteCoord = #56; /* + Writes a single value suitable for a map coordinate axis. The precision is not strictly specified but is assumed to be of at least 13.3 fixed-point precision (ie: +/-4k with 1/8th precision). */ + +void(float to, float val) WriteAngle = #57; /* + Writes a single value suitable for an angle axis. The precision is not strictly specified but is assumed to be 8bit, giving 256 notches instead of the assumed 360 range passed in. */ + +void(float to, string val) WriteString = #58; /* + Writes a variable-length null terminated string. There are length limits. The codepage is not translated, so be sure that client+server agree on whether utf-8 is being used or not (or just stick to ascii+markup). */ + +void(float to, entity val) WriteEntity = #59; /* + Writes the index of the specified entity (the network data size is not specified). This can be read clientside using the readentitynum builtin, with caveats. */ + +#endif +#if defined(CSQC) || defined(SSQC) +float(float angle) sin = #60; /* Part of DP_QC_SINCOSSQRTPOW + Forgive me father, for I have trigonometry homework. */ + +float(float angle) cos = #61; /* Part of DP_QC_SINCOSSQRTPOW*/ +float(float value) sqrt = #62; /* Part of DP_QC_SINCOSSQRTPOW*/ +#endif +#ifdef SSQC +float(float a, float n) modulo = #0:modulo; +#endif +#if defined(CSQC) || defined(SSQC) +void(entity ent) changepitch = #63; /* Part of DP_QC_CHANGEPITCH*/ +void(entity ent, entity ignore) tracetoss = #64; +string(entity ent) etos = #65; /* Part of DP_QC_ETOS*/ +void(float step) movetogoal = #67; /* + Runs lots and lots of fancy logic in order to try to step the entity the specified distance towards its goalentity. */ + +string(string s) precache_file = #68; /* + This builtin does nothing. It was used only as a hint for pak generation. */ + +void(entity e) makestatic = #69; /* + Sends a copy of the entity's renderable fields to all clients, and REMOVES the entity, preventing further changes. This means it will be unmutable and non-solid. */ + +#endif +#ifdef SSQC +void(string mapname, optional string newmapstartspot) changelevel = #70; /* + Attempts to change the map to the named map. If 'newmapstartspot' is specified, the state of the current map will be preserved, and the argument will be passed to the next map in the 'startspot' global, and the next map will be loaded from archived state if it was previously visited. If not specified, all archived map states will be purged. */ + +#endif +#if defined(CSQC) || defined(SSQC) +void(string cvarname, string valuetoset) cvar_set = #72; /* + Instantly sets a cvar to the given string value. Warning: the resulting string includes apostrophies surrounding the result. You may wish to use sprintf instead. */ + +#endif +#ifdef SSQC +void(entity ent, string text, optional string text2, optional string text3, optional string text4, optional string text5, optional string text6, optional string text7) centerprint = #73; +#endif +#if defined(CSQC) || defined(SSQC) +void (vector pos, string samp, float vol, float atten) ambientsound = #74; +string(string str) precache_model2 = #75; +string(string str) precache_sound2 = #76; +string(string str) precache_file2 = #77; +#endif +#ifdef SSQC +void(entity player) setspawnparms = #78; +float() ex_finaleFinished = #0:ex_finaleFinished; /* + Behaviour is undocumented. */ + +void(entity client, string sample) ex_localsound = #0:ex_localsound; /* + Behaviour is undocumented. */ + +void(entity ent, string text, optional string s0, optional string s1, optional string s2, optional string s3, optional string s4, optional string s5) ex_centerprint = #0:ex_centerprint; /* + Remaster: Sends the strings to the client, which will order according to {#}. Also substitutes localised strings for $NAME strings. */ + +void(string s, optional string s0, optional string s1, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6) ex_bprint = #0:ex_bprint; /* + Remaster: Sends the strings to all clients, which will order them according to {#}. Also substitutes localised strings for $NAME strings. */ + +void(entity client, string s, optional string s0, optional string s1, optional string s2, optional string s3, optional string s4, optional string s5) ex_sprint = #0:ex_sprint; /* + Remaster: Sends the strings to the client, which will order according to {#}. Also substitutes localised strings for $NAME strings. */ + +float(entity playerEnt) ex_CheckPlayerEXFlags = #0:ex_CheckPlayerEXFlags; /* + Behaviour is undocumented. */ + +void(entity killer, entity killee) logfrag = #79; /* Part of QW_ENGINE*/ +#endif +#if defined(CSQC) || defined(SSQC) +string(entity e, string key) infokey = #80; /* Part of FTE_QC_INFOKEY, QW_ENGINE + If e is world, returns the field 'key' from either the serverinfo or the localinfo. If e is a player, returns the value of 'key' from the player's userinfo string. There are a few special exceptions, like 'ip' which is not technically part of the userinfo. */ + +#endif +#ifdef SSQC +float(entity e, string key) infokeyf = #0:infokeyf; /* + Identical to regular infokey, except returns a float. */ + +int(entity e, string key, optional void *outbuf, int outbufsize) infokey_blob = #0:infokey_blob; /* + Retrieves a user's blob size, and optionally writes it to the specified buffer. */ + +#endif +#if defined(CSQC) || defined(SSQC) +float(string) stof = #81; /* Part of FRIK_FILE, FTE_QC_INFOKEY, FTE_STRINGS, QW_ENGINE, ZQ_QC_STRINGS*/ +#endif +#ifdef SSQC +#define unicast(pl,reli) do{msg_entity = pl; multicast('0 0 0', reli?MULITCAST_ONE_R:MULTICAST_ONE);}while(0) +void(vector where, float set) multicast = #82; /* Part of EXT_CSQC, FTE_QC_MULTICAST + Once the MSG_MULTICAST network message buffer has been filled with data, this builtin is used to dispatch it to the given target, filtering by pvs for reduced network bandwidth. */ + +DEP void(entity to, string str) redirectcmd = #101; /* Part of ??MVDSV_BUILTINS + Executes a single console command, and sends the text generated by it to the specified player. The command will be executed at the end of the frame once QC is no longer running - you may wish to pre/postfix it with 'echo'. */ + +#endif +#if defined(CSQC) || defined(SSQC) +string(float style, optional __out vector rgb) getlightstyle = #0:getlightstyle; /* + Obtains the light style string for the given style. */ + +vector(float style) getlightstylergb = #0:getlightstylergb; /* + Obtains the current rgb value of the specified light style. In csqc, this is correct with regard to the current frame, while ssqc gives no guarentees about time and ignores client cvars. Note: use getlight if you want the actual light value at a point. */ + +#endif +#ifdef SSQC +void(float style, float val, optional vector rgb) lightstylestatic = #5; /* + Sets the lightstyle to an explicit numerical level. From Hexen2. */ + +#endif +#if defined(CSQC) || defined(SSQC) +void(vector start, vector mins, vector maxs, vector end, float nomonsters, entity ent) tracebox = #90; /* Part of DP_QC_TRACEBOX + Exactly like traceline, but a box instead of a uselessly thin point. Acceptable sizes are limited by bsp format, q1bsp has strict acceptable size values. */ + +vector() randomvec = #91; /* Part of DP_QC_RANDOMVEC + Returns a vector with random values. Each axis is independantly a value between -1 and 1 inclusive. */ + +vector(vector org) getlight = #92; /* Part of DP_QC_GETLIGHT*/ +float(string cvarname, string defaultvalue) registercvar = #93; /* Part of DP_REGISTERCVAR + Creates a new cvar on the fly. If it does not already exist, it will be given the specified value. If it does exist, this is a no-op. + This builtin has the limitation that it does not apply to configs or commandlines. Such configs will need to use the set or seta command causing this builtin to be a noop. + In engines that support it, you will generally find the autocvar feature easier and more efficient to use. */ + +float(float a, float b, ...) min = #94; /* Part of DP_QC_MINMAXBOUND + Returns the lowest value of its arguments. */ + +float(float a, float b, ...) max = #95; /* Part of DP_QC_MINMAXBOUND + Returns the highest value of its arguments. */ + +float(float minimum, float val, float maximum) bound = #96; /* Part of DP_QC_MINMAXBOUND + Returns val, unless minimum is higher, or maximum is less. */ + +float(float value, float exp) pow = #97; /* Part of DP_QC_SINCOSSQRTPOW*/ +#endif +float(float v, optional float base) logarithm = #0:logarithm; /* + Determines the logarithm of the input value according to the specified base. This can be used to calculate how much something was shifted by. */ + +#if defined(CSQC) || defined(SSQC) +#define findentity findfloat +entity(entity start, .__variant fld, __variant match) findfloat = #98; /* Part of DP_QC_FINDFLOAT + Equivelent to the find builtin, but instead of comparing strings contents, this builtin compares the raw values. This builtin requires multiple calls in order to scan all entities - set start to the previous call's return value. + world is returned when there are no more entities. */ + +float(string extname) checkextension = #99; /* + Checks for an extension by its name (eg: checkextension("FRIK_FILE") says that its okay to go ahead and use strcat). + Use cvar("pr_checkextension") to see if this builtin exists. */ + +#endif +float(__variant funcref) checkbuiltin = #0:checkbuiltin; /* + Checks to see if the specified builtin is supported/mapped. This is intended as a way to check for #0 functions, allowing for simple single-builtin functions. Warning, if two different engines map different builtins to the same number, then this function will not tell you which will be called, only that it won't crash (the exception being #0, which are remapped as available). */ + +#ifdef SSQC +float(string builtinname) builtin_find = #100; /* + Looks to see if the named builtin is valid, and returns the builtin number it exists at. */ + +#endif +#if defined(CSQC) || defined(SSQC) +float(float value) anglemod = #102; +float(float newangle, float oldangle) anglesub = #0:anglesub; /* + Returns newangle-oldangle, except returning the shortest route around a circle so yields a result between -180 and +180. */ + +#endif +#ifdef SSQC +DEP_CSQC void(string slot, string picname, float x, float y, float zone, optional entity player) showpic = #104; /* Part of TEI_SHOWLMP2*/ +DEP_CSQC void(string slot, optional entity player) hidepic = #105; /* Part of TEI_SHOWLMP2*/ +DEP_CSQC void(string slot, float x, float y, float zone, optional entity player) movepic = #106; /* Part of TEI_SHOWLMP2*/ +DEP_CSQC void(string slot, string picname, optional entity player) changepic = #107; /* Part of TEI_SHOWLMP2*/ +#endif +#if defined(CSQC) || defined(SSQC) +filestream(string filename, float mode, optional float mmapminsize) fopen = #110; /* Part of FRIK_FILE + Opens a file, typically prefixed with "data/", for either read or write access. */ + +void(filestream fhandle) fclose = #111; /* Part of FRIK_FILE*/ +string(filestream fhandle) fgets = #112; /* Part of FRIK_FILE + Reads a single line out of the file. The new line character is not returned as part of the string. Returns the null string on EOF (use if not(string) to easily test for this, which distinguishes it from the empty string which is returned if the line being read is blank */ + +void(filestream fhandle, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7) fputs = #113; /* Part of FRIK_FILE + Writes the given string(s) into the file. For compatibility with fgets, you should ensure that the string is terminated with a \n - this will not otherwise be done for you. It is up to the engine whether dos or unix line endings are actually written. */ + +#endif +int(filestream fhandle, void *ptr, int size) fread = #0:fread; /* Part of FTE_QC_FILE_BINARY + Reads binary data out of the file. Returns truncated lengths if the read exceeds the length of the file. */ + +int(filestream fhandle, void *ptr, int size) fwrite = #0:fwrite; /* Part of FTE_QC_FILE_BINARY + Writes binary data out of the file. */ + +#define ftell fseek //c compat +int(filestream fhandle, optional int newoffset) fseek = #0:fseek; /* Part of FTE_QC_FILE_BINARY + Changes the current position of the file, if specified. Returns prior position, in bytes. */ + +int(filestream fhandle, optional int newsize) fsize = #0:fsize; /* Part of FTE_QC_FILE_BINARY + Reports the total size of the file, in bytes. Can also be used to truncate/extend the file */ + +#if defined(CSQC) || defined(SSQC) +float(string s) strlen = #114; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ +string(string s1, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7, optional string s8) strcat = #115; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ +string(string s, float start, float length) substring = #116; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ +vector(string s) stov = #117; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ +FTEDEP("Redundant") string(string s, ...) strzone = #118; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS + Create a semi-permanent copy of a string that only becomes invalid once strunzone is called on the string (instead of when the engine assumes your string has left scope). This builtin has become redundant in FTEQW due to the FTE_QC_PERSISTENTTEMPSTRINGS extension and is now functionally identical to strcat for compatibility with old engines+mods. */ + +FTEDEP("Redundant") void(string s) strunzone = #119; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS + Destroys a string that was allocated by strunzone. Further references to the string MAY crash the game. In FTE, this function became redundant and now does nothing. */ + +#endif +void*(int bytes) createbuffer = #0:createbuffer; /* + Returns a temporary buffer that can be written to / read from. The buffer will be garbage collected and thus cannot be explicitly freed. Tempstrings and buffer references must not be stored into the buffer as the garbage collector will not scan these. */ + +#ifdef SSQC +void(string cvar, float val) cvar_setf = #176; +#endif +#if defined(CSQC) || defined(SSQC) +void(string soundname, optional float channel, optional float volume) localsound = #177; /* + Plays a sound... locally... probably best not to call this from ssqc. Also disables reverb. */ + +float(string modelname, optional float queryonly) getmodelindex = #200; /* + Acts as an alternative to precache_model(foo);setmodel(bar, foo); return bar.modelindex; + If queryonly is set and the model was not previously precached, the builtin will return 0 without needlessly precaching the model. */ + +float(string soundname, optional float queryonly) getsoundindex = #0:getsoundindex; /* + Provides a way to query if a sound is already precached or not. The return value can also be checked for <=255 to see if it'll work over any network protocol. The sound index can also be used for writebyte hacks, but this is discouraged - use SOUNDFLAG_UNICAST instead. */ + +__variant(float prnum, string funcname, ...) externcall = #201; /* Part of FTE_MULTIPROGS + Directly call a function in a different/same progs by its name. + prnum=0 is the 'default' or 'main' progs. + prnum=-1 means current progs. + prnum=-2 will scan through the active progs and will use the first it finds. */ + +float(string progsname) addprogs = #202; /* Part of FTE_MULTIPROGS + Loads an additional .dat file into the current qcvm. The returned handle can be used with any of the externcall/externset/externvalue builtins. + There are cvars that allow progs to be loaded automatically. */ + +__variant(float prnum, string varname) externvalue = #203; /* Part of FTE_MULTIPROGS + Reads a global in the named progs by the name of that global. + prnum=0 is the 'default' or 'main' progs. + prnum=-1 means current progs. + prnum=-2 will scan through the active progs and will use the first it finds. */ + +void(float prnum, __variant newval, string varname) externset = #204; /* Part of FTE_MULTIPROGS + Sets a global in the named progs by name. + prnum=0 is the 'default' or 'main' progs. + prnum=-1 means current progs. + prnum=-2 will scan through the active progs and will use the first it finds. */ + +void(entity portal, float state) openportal = #207; /* + Opens or closes the portals associated with a door or some such on q2 or q3 maps. On Q2BSPs, the entity should be the 'func_areaportal' entity - its style field will say which portal to open. On Q3BSPs, the entity is the door itself, the portal will be determined by the two areas found from a preceding setorigin call. */ + +#endif +#ifdef SSQC +float(float attributes, string effectname, ...) RegisterTempEnt = #208; /* Part of FTE_PEXT_CUSTOMTENTS*/ +void(float type, vector pos, ...) CustomTempEnt = #209; /* Part of FTE_PEXT_CUSTOMTENTS*/ +float(optional float sleeptime) fork = #210; /* Part of FTE_MULTITHREADED + When called, this builtin simply returns. Twice. + The current 'thread' will return instantly with a return value of 0. The new 'thread' will return after sleeptime seconds with a return value of 1. See documentation for the 'sleep' builtin for limitations/requirements concerning the new thread. Note that QC should probably call abort in the new thread, as otherwise the function will return to the calling qc function twice also. */ + +#endif +void(optional __variant ret) abort = #211; /* Part of FTE_MULTITHREADED + QC execution is aborted. Parent QC functions on the stack will be skipped, effectively this forces all QC functions to 'return ret' until execution returns to the engine. If ret is ommited, it is assumed to be 0. */ + +#ifdef SSQC +void(float sleeptime) sleep = #212; /* Part of FTE_MULTITHREADED + Suspends the current QC execution thread for 'sleeptime' seconds. + Other QC functions can and will be executed in the interim, including changing globals and field state (but not simultaneously). + The self and other globals will be restored when the thread wakes up (or set to world if they were removed since the thread started sleeping). Locals will be preserved, but will not be protected from remove calls. + If the engine is expecting the QC to return a value (even in the parent/root function), the value 0 shall be used instead of waiting for the qc to resume. */ + +void(entity player, string key, string value) forceinfokey = #213; /* Part of FTE_FORCEINFOKEY + Directly changes a user's info without pinging off the client. Also allows explicitly setting * keys, including *spectator. Does not affect the user's config or other servers. */ + +void(entity player, string key, void *data, int size) forceinfokeyblob = #0:forceinfokeyblob; /* Part of FTE_INFOBLOBS + Directly changes a user's info without pinging off the client. Also allows explicitly setting * keys, including *spectator. Does not affect the user's config or other servers. */ + +#endif +#if defined(CSQC) || defined(SSQC) +void(vector org, vector dmin, vector dmax, float colour, float effect, float count) particle2 = #215; /* Part of FTE_HEXEN2*/ +void(vector org, vector box, float colour, float effect, float count) particle3 = #216; /* Part of FTE_HEXEN2*/ +void(vector org, float radius, float colour, float effect, float count) particle4 = #217; /* Part of FTE_HEXEN2*/ +float(float number, float quantity) bitshift = #218; /* Part of EXT_BITSHIFT*/ +void(vector pos) te_lightningblood = #219; /* Part of FTE_TE_STANDARDEFFECTBUILTINS*/ +#endif +float(string s1, string sub, optional float startidx) strstrofs = #221; /* Part of FTE_STRINGS + Returns the 0-based offset of sub within the s1 string, or -1 if sub is not in s1. + If startidx is set, this builtin will ignore matches before that 0-based offset. */ + +float(string str, float index) str2chr = #222; /* Part of FTE_STRINGS + Retrieves the character value at offset 'index'. */ + +string(float chr, ...) chr2str = #223; /* Part of FTE_STRINGS + The input floats are considered character values, and are concatenated. */ + +string(float ccase, float redalpha, float redchars, string str, ...) strconv = #224; /* Part of FTE_STRINGS + Converts quake chars in the input string amongst different representations. + ccase specifies the new case for letters. + 0: not changed. + 1: forced to lower case. + 2: forced to upper case. + redalpha and redchars switch between colour ranges. + 0: no change. + 1: Forced white. + 2: Forced red. + 3: Forced gold(low) (numbers only). + 4: Forced gold (high) (numbers only). + 5+6: Forced to white and red alternately. + You should not use this builtin in combination with UTF-8. */ + +string(float pad, string str1, ...) strpad = #225; /* Part of FTE_STRINGS + Pads the string with spaces, to ensure its a specific length (so long as a fixed-width font is used, anyway). If pad is negative, the spaces are added on the left. If positive the padding is on the right. */ + +infostring(infostring old, string key, string value) infoadd = #226; /* Part of FTE_STRINGS + Returns a new tempstring infostring with the named value changed (or added if it was previously unspecified). Key and value may not contain the \ character. */ + +string(infostring info, string key) infoget = #227; /* Part of FTE_STRINGS + Reads a named value from an infostring. The returned value is a tempstring */ + +#define strcmp strncmp +float(string s1, string s2, optional float len, optional float s1ofs, optional float s2ofs) strncmp = #228; /* Part of FTE_STRINGS + Compares up to 'len' chars in the two strings. s1ofs allows you to treat s2 as a substring to compare against, or should be 0. + Returns 0 if the two strings are equal, a negative value if s1 appears numerically lower, and positive if s1 appears numerically higher. */ + +float(string s1, string s2) strcasecmp = #229; /* Part of FTE_STRINGS + Compares the two strings without case sensitivity. + Returns 0 if they are equal. The sign of the return value may be significant, but should not be depended upon. */ + +float(string s1, string s2, float len, optional float s1ofs, optional float s2ofs) strncasecmp = #230; /* Part of FTE_STRINGS + Compares up to 'len' chars in the two strings without case sensitivity. s1ofs allows you to treat s2 as a substring to compare against, or should be 0. + Returns 0 if they are equal. The sign of the return value may be significant, but should not be depended upon. */ + +string(string s) strtrim = #0:strtrim; /* + Trims the whitespace from the start+end of the string. */ + +#if defined(CSQC) || defined(SSQC) +__deprecated("Use strftime.") void() calltimeofday = #231; /* Part of FTE_CALLTIMEOFDAY + Asks the engine to instantly call the qc's 'timeofday' function, before returning. For compatibility with mvdsv. + timeofday should have the prototype: void(float secs, float mins, float hour, float day, float mon, float year, string strvalue) + The strftime builtin is more versatile and less weird. */ + +#endif +#ifdef SSQC +void(float num, float type, .__variant fld) clientstat = #232; /* Part of EXT_CSQC + Specifies what data to use in order to send various stats, in a client-specific way. + 'num' should be a value between 32 and 127, other values are reserved. + 'type' must be set to one of the EV_* constants, one of EV_FLOAT, EV_STRING, EV_INTEGER, EV_ENTITY. + fld must be a reference to the field used, each player will be sent only their own copy of these fields. */ + +void(float num, float type, string name) globalstat = #233; /* + Specifies what data to use in order to send various stats, in a non-client-specific way. num and type are as in clientstat, name however, is the name of the global to read in the form of a string (pass "foo"). */ + +void(float num, float type, __variant *address) pointerstat = #0:pointerstat; /* + Specifies what data to use in order to send various stats, in a non-client-specific way. num and type are as in clientstat, address however, is the address of the variable you would like to use (pass &foo). */ + +void(entity ent, vector sendflags, entity unicastplayer) setsendneeded = #0:setsendneeded; /* + Flags the entity as needing to be resent. This builtin allows for more bits than supported by the SendEntity field, as well as allows flagging sends to specific players. */ + +float(entity player) isbackbuffered = #234; /* Part of FTE_ISBACKBUFFERED + Returns if the given player's network buffer will take multiple network frames in order to clear. If this builtin returns non-zero, you should delay or reduce the amount of reliable (and also unreliable) data that you are sending to that client. */ + +#endif +#if defined(CSQC) || defined(SSQC) +void(vector angle) rotatevectorsbyangle = #235; /* + rotates the v_forward,v_right,v_up matrix by the specified angles. */ + +void(vector fwd, vector right, vector up) rotatevectorsbyvectors = #236; +float(float mdlindex, string skinname) skinforname = #237; +#endif +#if defined(CSQC) || defined(MENU) +float(string shadername, optional string defaultshader, ...) shaderforname = #238; /* Part of FTE_FORCESHADER + Caches the named shader and returns a handle to it. + If the shader could not be loaded from disk (missing file or ruleset_allow_shaders 0), it will be created from the 'defaultshader' string if specified, or a 'skin shader' default will be used. + defaultshader if not empty should include the outer {} that you would ordinarily find in a shader. */ + +#endif +#ifdef CSQC +void(string shadername, string replacement, float timeoffset) remapshader = #0:remapshader; /* + All surfaces drawn with the specified shader will instead be drawn using the specified replacement shader. Shaders can be remapped to something else later by using the same source shadername. This is mostly useful for worldmodel surfaces (eg showing which team is currently winning). Entities should generally use setcustomskin or forceshader instead. Remaps will be forgotten on vid_reload, but can be reapplied via CSQC_RendererRestarted. */ + +#endif +#if defined(CSQC) || defined(SSQC) +void(vector org, optional float count) te_bloodqw = #239; /* Part of FTE_TE_STANDARDEFFECTBUILTINS*/ +#endif +#ifdef SSQC +void(entity ent) te_muzzleflash = #0:te_muzzleflash; +#endif +#if defined(CSQC) || defined(SSQC) +float(vector viewpos, entity entity) checkpvs = #240; /* Part of FTE_QC_CHECKPVS*/ +#endif +#ifdef SSQC +entity(string match, optional float matchnum) matchclientname = #241; /* Part of FTE_QC_MATCHCLIENTNAME*/ +#endif +float(string destaddress, string content) sendpacket = #242; /* Part of FTE_QC_SENDPACKET + Sends a UDP packet to the specified destination. Note that the payload will be prefixed with four 255 bytes as a sort of security feature. */ + +#ifdef CSQC +vector(entity ent, float tagnum) rotatevectorsbytag = #244; +#endif +#if defined(CSQC) || defined(SSQC) +float(float dividend, float divisor) mod = #245; +#endif +#ifdef SSQC +float(optional string host, optional string user, optional string pass, optional string defaultdb, optional string driver) sqlconnect = #250; /* Part of FTE_SQL*/ +void(float serveridx) sqldisconnect = #251; /* Part of FTE_SQL*/ +float(float serveridx, void(float serveridx, float queryidx, float rows, float columns, float eof, float firstrow) callback, float querytype, string query) sqlopenquery = #252; /* Part of FTE_SQL*/ +void(float serveridx, float queryidx) sqlclosequery = #253; /* Part of FTE_SQL*/ +string(float serveridx, float queryidx, float row, float column) sqlreadfield = #254; /* Part of FTE_SQL*/ +string(float serveridx, optional float queryidx) sqlerror = #255; /* Part of FTE_SQL*/ +string(float serveridx, string data) sqlescape = #256; /* Part of FTE_SQL*/ +string(float serveridx) sqlversion = #257; /* Part of FTE_SQL*/ +float(float serveridx, float queryidx, float row, float column) sqlreadfloat = #258; /* Part of FTE_SQL*/ +int(float serveridx, float queryidx, float row, float column, __variant *ptr, int maxsize) sqlreadblob = #0:sqlreadblob; +string(float serveridx, __variant *ptr, int maxsize) sqlescapeblob = #0:sqlescapeblob; +#endif +typedef struct json_s *json_t; +accessor jsonnode : json_t; +jsonnode(string) json_parse = #0:json_parse; /* + Parses the given JSON string. */ + +void(jsonnode) json_free = #0:json_free; /* + Frees a json tree and all of its children. Must only be called on the root node. */ + +enum json_type_e : int +{ + JSON_TYPE_STRING, + JSON_TYPE_NUMBER, + JSON_TYPE_OBJECT, + JSON_TYPE_ARRAY, + JSON_TYPE_TRUE, + JSON_TYPE_FALSE, + JSON_TYPE_NULL +}; +json_type_e(jsonnode node) json_get_value_type = #0:json_get_value_type; /* + Get type of a JSON value. */ + +int(jsonnode node) json_get_integer = #0:json_get_integer; /* + Get an integer from a json node. */ + +float(jsonnode node) json_get_float = #0:json_get_float; /* + Get a float from a json node. */ + +string(jsonnode node) json_get_string = #0:json_get_string; /* + Get a string from a value. Returns a null string if its not a string type. */ + +jsonnode(jsonnode node, string) json_find_object_child = #0:json_find_object_child; /* + Find a child of a json object by name. Returns NULL if the handle couldn't be found. */ + +int(jsonnode node) json_get_length = #0:json_get_length; /* + Get the length of a json array or object. Returns 0 if its not an array. */ + +jsonnode(jsonnode node, int childindex) json_get_child_at_index = #0:json_get_child_at_index; /* + Get the nth child of a json array or object. Returns NULL if the index is out of range. */ + +string(jsonnode node) json_get_name = #0:json_get_name; /* + Gets the object's name (useful if you're using json_get_child_at_index to walk an object's children for whatever reason). */ + +string(string javascript) js_run_script = #0:js_run_script; /* + Runs the provided javascript snippet. This builtin functions only in emscripten builds, returning a null string on other systems (or if the script evaluates to null). */ + +#if defined(CSQC) || defined(SSQC) +int(string) stoi = #259; /* Part of FTE_QC_INTCONV + Converts the given string into a true integer. Base 8, 10, or 16 is determined based upon the format of the string. */ + +string(int) itos = #260; /* Part of FTE_QC_INTCONV + Converts the passed true integer into a base10 string. */ + +int(string) stoh = #261; /* Part of FTE_QC_INTCONV + Reads a base-16 string (with or without 0x prefix) as an integer. Bugs out if given a base 8 or base 10 string. :P */ + +string(int) htos = #262; /* Part of FTE_QC_INTCONV + Formats an integer as a base16 string, with leading 0s and no prefix. Always returns 8 characters. */ + +#endif +int(float) ftoi = #0:ftoi; /* Part of FTE_QC_INTCONV + Converts the given float into a true integer without depending on extended qcvm instructions. */ + +float(int, optional float shift, float mask=24) itof = #0:itof; /* Part of FTE_QC_INTCONV + Converts the given true integer into a float without depending on extended qcvm instructions. If shift and mask are specified then only specific parts of the integer will be cast to float. */ + +#if defined(CSQC) || defined(SSQC) +float(float modlindex, optional float useabstransforms) skel_create = #263; /* Part of FTE_CSQC_SKELETONOBJECTS + Allocates a new uninitiaised skeletal object, with enough bone info to animate the given model. + eg: self.skeletonobject = skel_create(self.modelindex); */ + +float(float skel, entity ent, float modelindex, float retainfrac, float firstbone, float lastbone, optional float addfrac) skel_build = #264; /* Part of FTE_CSQC_SKELETONOBJECTS + Animation data (according to the entity's frame info) is pulled from the specified model and blended into the specified skeletal object. + If retainfrac is set to 0 on the first call and 1 on the others, you can blend multiple animations together according to the addfrac value. The final weight should be 1. Other values will result in scaling and/or other weirdness. You can use firstbone and lastbone to update only part of the skeletal object, to allow legs to animate separately from torso, use 0 for both arguments to specify all, as bones are 1-based. */ + +typedef struct +{ + int sourcemodelindex; /*frame data will be imported from this model, bones must be compatible*/ + int reserved; + int firstbone; + int lastbone; + float prescale; /*0 destroys existing data, 1 retains it*/ + float scale[4]; /*you'll need to do lerpfrac manually*/ + int animation[4]; + float animationtime[4]; + /*halflife models*/ + float subblend[2]; + float controllers[5]; +} skelblend_t; +float(float skel, int numblends, skelblend_t *weights, int structsize) skel_build_ptr = #0:skel_build_ptr; /* + Like skel_build, but slightly simpler. */ + +float(float skel) skel_get_numbones = #265; /* Part of FTE_CSQC_SKELETONOBJECTS + Retrives the number of bones in the model. The valid range is 1<=bone<=numbones. */ + +string(float skel, float bonenum) skel_get_bonename = #266; /* Part of FTE_CSQC_SKELETONOBJECTS + Retrieves the name of the specified bone. Mostly only for debugging. */ + +float(float skel, float bonenum) skel_get_boneparent = #267; /* Part of FTE_CSQC_SKELETONOBJECTS + Retrieves which bone this bone's position is relative to. Bone 0 refers to the entity's position rather than an actual bone */ + +float(float skel, string tagname) skel_find_bone = #268; /* Part of FTE_CSQC_SKELETONOBJECTS + Finds a bone by its name, from the model that was used to create the skeletal object. */ + +vector(float skel, float bonenum) skel_get_bonerel = #269; /* Part of FTE_CSQC_SKELETONOBJECTS + Gets the bone position and orientation relative to the bone's parent. Return value is the offset, and v_forward, v_right, v_up contain the orientation. */ + +vector(float skel, float bonenum) skel_get_boneabs = #270; /* Part of FTE_CSQC_SKELETONOBJECTS + Gets the bone position and orientation relative to the entity. Return value is the offset, and v_forward, v_right, v_up contain the orientation. + Use gettaginfo for world coord+orientation. */ + +void(float skel, float bonenum, vector org, optional vector fwd, optional vector right, optional vector up) skel_set_bone = #271; /* Part of FTE_CSQC_SKELETONOBJECTS + Sets a bone position relative to its parent. If the orientation arguments are not specified, v_forward+v_right+v_up are used instead. */ + +void(float skel, float bonenum, vector org, optional vector fwd, optional vector right, optional vector up) skel_premul_bone = #272; /* Part of FTE_CSQC_SKELETONOBJECTS + Transforms a single bone by a matrix. You can use makevectors to generate a rotation matrix from an angle. */ + +void(float skel, float startbone, float endbone, vector org, optional vector fwd, optional vector right, optional vector up) skel_premul_bones = #273; /* Part of FTE_CSQC_SKELETONOBJECTS + Transforms an entire consecutive range of bones by a matrix. You can use makevectors to generate a rotation matrix from an angle, but you'll probably want to divide the angle by the number of bones. */ + +void(float skel, float bonenum, vector org, optional vector fwd, optional vector right, optional vector up) skel_postmul_bone = #0:skel_postmul_bone; /* + Transforms a single bone by a matrix. You can use makevectors to generate a rotation matrix from an angle. */ + +void(float skeldst, float skelsrc, float startbone, float entbone) skel_copybones = #274; /* Part of FTE_CSQC_SKELETONOBJECTS + Copy bone data from one skeleton directly into another. */ + +void(float skel) skel_delete = #275; /* Part of FTE_CSQC_SKELETONOBJECTS + Deletes a skeletal object. The actual delete is delayed, allowing the skeletal object to be deleted in an entity's predraw function yet still be valid by the time the addentity+renderscene builtins need it. Also uninstanciates any ragdoll currently in effect on the skeletal object. */ + +float(float modidx, string framename) frameforname = #276; /* Part of FTE_CSQC_SKELETONOBJECTS + Looks up a framegroup from a model by name, avoiding the need for hardcoding. Returns -1 on error. */ + +float(float modidx, float framenum) frameduration = #277; /* Part of FTE_CSQC_SKELETONOBJECTS + Retrieves the duration (in seconds) of the specified framegroup. */ + +float(float modidx, int actionid) frameforaction = #0:frameforaction; /* + Returns a random frame/animation for the specified mod-defined action, or -1 if no animations have the specified action. */ + +void(float modidx, float framenum, __inout float basetime, float targettime, void(float timestamp, int code, string data) callback) processmodelevents = #0:processmodelevents; /* Part of FTE_GFX_MODELEVENTS + Calls a callback for each event that has been reached. Basetime is set to targettime. */ + +float(float modidx, float framenum, __inout float basetime, float targettime, __out int code, __out string data) getnextmodelevent = #0:getnextmodelevent; /* Part of FTE_GFX_MODELEVENTS + Reports the next event within a model's animation. Returns a boolean if an event was found between basetime and targettime. Writes to basetime,code,data arguments (if an event was found, basetime is set to the event's time, otherwise to targettime). + WARNING: this builtin cannot deal with multiple events with the same timestamp (only the first will be reported). */ + +float(float modidx, float framenum, int eventidx, __out float timestamp, __out int code, __out string data) getmodeleventidx = #0:getmodeleventidx; /* Part of FTE_GFX_MODELEVENTS + Reports an indexed event within a model's animation. Writes to timestamp,code,data arguments on success. Returns false if the animation/event/model was out of range/invalid. Does not consider looping animations (retry from index 0 if it fails and you know that its a looping animation). This builtin is more annoying to use than getnextmodelevent, but can be made to deal with multiple events with the exact same timestamp. */ + +#endif +#define dotproduct(v1,v2) ((vector)(v1)*(vector)(v2)) +vector(vector v1, vector v2) crossproduct = #0:crossproduct; /* Part of FTE_QC_CROSSPRODUCT + Small helper function to calculate the crossproduct of two vectors. */ + +#if defined(CSQC) || defined(SSQC) +float(entity pusher, vector move, vector amove) pushmove = #0:pushmove; +__variant(float action, optional vector pos, optional float radius, optional float quant, ...) terrain_edit = #278; /* Part of FTE_TERRAIN_MAP + Realtime terrain editing. Actions are the TEREDIT_ constants. */ + +typedef struct +{ + string shadername; + vector planenormal; + float planedist; + vector sdir; + float sbias; + vector tdir; + float tbias; +} brushface_t; +int(float modelidx, int brushid, brushface_t *out_faces, int maxfaces, int *out_contents) brush_get = #0:brush_get; /* Part of FTE_RAW_MAP + Queries a brush's information. You must pre-allocate the face array for the builtin to write to. Return value is the number of faces retrieved, 0 on error. */ + +int(float modelidx, brushface_t *in_faces, int numfaces, int contents, optional int brushid) brush_create = #0:brush_create; /* Part of FTE_RAW_MAP + Inserts a new brush into the model. Return value is the new brush's id. */ + +void(float modelidx, int brushid) brush_delete = #0:brush_delete; /* Part of FTE_RAW_MAP + Destroys the specified brush. */ + +float(float modelid, int brushid, int faceid, float selectedstate) brush_selected = #0:brush_selected; /* Part of FTE_RAW_MAP + Allows you to easily set transient visual properties of a brush. returns old value. selectedstate=-1 changes nothing (called for its return value). */ + +int(float modelid, int brushid, int faceid, vector *points, int maxpoints) brush_getfacepoints = #0:brush_getfacepoints; /* Part of FTE_RAW_MAP + Returns the list of verticies surrounding the given face. If face is 0, returns the center of the brush (if space for 1 point) or the mins+maxs (if space for 2 points). */ + +int(int faceid, brushface_t *in_faces, int numfaces, vector *points, int maxpoints) brush_calcfacepoints = #0:brush_calcfacepoints; /* Part of FTE_RAW_MAP + Determines the points of the specified face, if the specified brush were to actually be created. */ + +int(float modelid, vector *planes, float *dists, int numplanes, int *out_brushes, int *out_faces, int maxresults) brush_findinvolume = #0:brush_findinvolume; /* Part of FTE_RAW_MAP + Allows you to easily obtain a list of brushes+faces within the given bounding region. If out_faces is not null, the same brush might be listed twice. */ + +typedef struct +{ + string shadername; + int contents; + int cpwidth; + int cpheight; + int tesswidth; + int tessheight; + vector texinfo;/*scalex,y,rot*/ +} patchinfo_t; +typedef struct +{ + vector xyz; + vector rgb; float a; + float s, t; +} patchvert_t; +#define patch_delete(modelidx,patchidx) brush_delete(modelidx,patchidx) +int(float modelidx, int patchid, patchvert_t *out_controlverts, int maxcp, patchinfo_t *out_info) patch_getcp = #0:patch_getcp; /* + Queries a patch's information. You must pre-allocate the face array for the builtin to write to. Return value is the total number of control verts that were retrieved, 0 on error. */ + +int(float modelidx, int patchid, patchvert_t *out_verts, int maxverts, __out patchinfo_t out_info) patch_getmesh = #0:patch_getmesh; /* + Queries a patch's information. You must pre-allocate the face array for the builtin to write to. Return value is the total number of control verts that were retrieved, 0 on error. */ + +int(float modelidx, int oldpatchid, patchvert_t *in_controlverts, patchinfo_t in_info) patch_create = #0:patch_create; /* + Inserts a new patch into the model. Return value is the new patch's id. */ + +typedef struct +{ + vector dest; + int linkflags; + float radius; +} nodeslist_t; +void(entity ent, vector dest, int denylinkflags, void(entity ent, vector dest, int numnodes, nodeslist_t *nodelist) callback) route_calculate = #0:route_calculate; /* + Begin calculating a route. The callback function will be called once the route has finished being calculated. The route must be memfreed once it is no longer needed. The route must be followed in reverse order (ie: the first node that must be reached is at index numnodes-1). If no route is available then the callback will be called with no nodes. */ + +void(optional entity ent, optional vector neworigin) touchtriggers = #279; /* + Triggers a touch events between self and every SOLID_TRIGGER entity that it is in contact with. This should typically just be the triggers touch functions. Also optionally updates the origin of the moved entity. */ + +#endif +#ifdef SSQC +void(float buf, float fl) WriteFloat = #280; /* + Writes a full 32bit float without any data conversions at all, for full precision. */ + +void(float buf, __double dbl) WriteDouble = #0:WriteDouble; /* + Writes a full 64bit double-precision float without any data conversions at all, for excessive precision. */ + +void(float buf, int fl) WriteInt = #0:WriteInt; /* + Writes all 4 bytes of a 32bit integer without truncating to a float first before converting back to an int (unlike WriteLong does, but otherwise equivelent). */ + +void(float buf, __int64 fl) WriteInt64 = #0:WriteInt64; /* + Writes all 8 bytes of a 64bit integer. This uses variable-length coding and will send only a single byte for any value between -64 and 63. */ + +void(float buf, __uint64 fl) WriteUInt64 = #0:WriteUInt64; /* + Writes all 8 bytes of a 64bit unsigned integer. Values between 0-127 will be sent in a single byte. */ + +#endif +#if defined(CSQC) || defined(SSQC) +float(entity skelent, string dollcmd, float animskel) skel_ragupdate = #281; /* Part of FTE_QC_RAGDOLL_WIP + Updates the skeletal object attached to the entity according to its origin and other properties. + if animskel is non-zero, the ragdoll will animate towards the bone state in the animskel skeletal object, otherwise they will pick up the model's base pose which may not give nice results. + If dollcmd is not set, the ragdoll will update (this should be done each frame). + If the doll is updated without having a valid doll, the model's default .doll will be instanciated. + commands: + doll foo.doll : sets up the entity to use the named doll file + dollstring TEXT : uses the doll file directly embedded within qc, with that extra prefix. + cleardoll : uninstanciates the doll without destroying the skeletal object. + animate 0.5 : specifies the strength of the ragdoll as a whole + animatebody somebody 0.5 : specifies the strength of the ragdoll on a specific body (0 will disable ragdoll animations on that body). + enablejoint somejoint 1 : enables (or disables) a joint. Disabling joints will allow the doll to shatter. */ + +float*(float skel) skel_mmap = #282; /* Part of FTE_QC_RAGDOLL_WIP + Map the bones in VM memory. They can then be accessed via pointers. Each bone is 12 floats, the four vectors interleaved (sadly). */ + +void(entity ent, float bonenum, vector org, optional vector angorfwd, optional vector right, optional vector up) skel_set_bone_world = #283; /* Part of FTE_QC_RAGDOLL_WIP + Sets the world position of a bone within the given entity's attached skeletal object. The world position is dependant upon the owning entity's position. If no orientation argument is specified, v_forward+v_right+v_up are used for the orientation instead. If 1 is specified, it is understood as angles. If 3 are specified, they are the forawrd/right/up vectors to use. */ + +string(float modidx, float framenum) frametoname = #284; +string(float modidx, float skin) skintoname = #285; +float(float resourcetype, float tryload, string resourcename) resourcestatus = #286; /* + resourcetype must be one of the RESTYPE_ constants. Returns one of the RESSTATE_ constants. Tryload 0 is a query only. Tryload 1 will attempt to reload the content if it was flushed. */ + +#endif +hashtable(float tabsize, optional float defaulttype) hash_createtab = #287; /* Part of FTE_QC_HASHTABLES + Creates a hash table object. + The tabsize argument is a performance hint and should generally be set to something similar to the number of entries expected, typically a power of two assumption. Too high simply wastes memory, too low results in extra string compares but no actual bugs. + defaulttype must be one of the EV_* values, if specified. + The hash table with index 0 is a game-persistant table and will NEVER be returned by this builtin (except as an error return). */ + +void(hashtable table) hash_destroytab = #288; /* Part of FTE_QC_HASHTABLES + Destroys a hash table object. */ + +void(hashtable table, string name, __variant value, optional float typeandflags) hash_add = #289; /* Part of FTE_QC_HASHTABLES + Adds the given key with the given value to the table. + If flags&HASH_REPLACE, the old value will be removed, otherwise if flags&HASH_ADD then a duplicate entry will be added with a second value (can be obtained via hash_get's index argument). + The type argument describes how the value should be stored in saved games, as well as providing constraints with the hash_get function. While you can claim that all variables are just vectors, being more precise can result in less issues with tempstrings or saved games - be sure to be explicit with EV_STRING where appropriate because tempstrings may be reclaimed before the get (especially with saved games or table 0). */ + +__variant(hashtable table, string name, optional __variant deflt, optional float requiretype, optional float index) hash_get = #290; /* Part of FTE_QC_HASHTABLES + Looks up the specified key name in the hash table. Returns deflt if the key was not found. + If requiretype is specified then the function will only consider entries of the matching type (allowing you to store both flags+strings under a single name without getting confused). + If index is specified then the function will ignore the first N entries with the same key (applicable only with entries added using HASH_ADD, not HASH_REPLACE), allowing you to store multiple entries. Keep querying higher indexes starting from 0 until it returns the deflt value. + You will usually need to cast the result of this function to a real datatype. */ + +__variant(hashtable table, string name) hash_delete = #291; /* Part of FTE_QC_HASHTABLES + removes the named key. returns the value of the object that was destroyed, or 0 on error. */ + +string(hashtable table, float idx) hash_getkey = #292; /* Part of FTE_QC_HASHTABLES + gets some random key name. add+delete can change return values of this, so don't blindly increment the key index if you're removing all. */ + +float(string name) checkcommand = #294; /* Part of FTE_QC_CHECKCOMMAND + Checks to see if the supplied name is a valid command, cvar, or alias. Returns 0 if it does not exist. */ + +string(string s) argescape = #295; /* + Marks up a string so that it can be reliably tokenized as a single argument later. */ + +#ifdef SSQC +void(string dest, string from, string cmd, string info) clusterevent = #0:clusterevent; /* + Only functions in mapcluster mode. Sends an event to whichever server the named player is on. The destination server can then dispatch the event to the client or handle it itself via the SV_ParseClusterEvent entrypoint. If dest is empty, the event is broadcast to ALL servers. If the named player can't be found, the event will be returned to this server with the cmd prefixed with 'error:'. */ + +string(entity player, optional string newnode) clustertransfer = #0:clustertransfer; /* + Only functions in mapcluster mode. Initiate transfer of the player to a different node. Can take some time. If dest is specified, returns null on error. Otherwise returns the current/new target node (or null if not transferring). */ + +#endif +#if defined(CSQC) || defined(SSQC) || defined(MENU) +float(float mdlidx) modelframecount = #0:modelframecount; /* + Retrieves the number of frames in the specified model. */ + +#endif +#if defined(CSQC) || defined(MENU) +void() clearscene = #300; /* + Forgets all rentities, polygons, and temporary dlights. Resets all view properties to their default values. */ + +#endif +#ifdef CSQC +void(float mask) addentities = #301; /* + Walks through all entities effectively doing this: + if (ent.drawmask&mask){ if (!ent.predaw()) addentity(ent); } + If mask&MASK_DELTA, non-csqc entities, particles, and related effects will also be added to the rentity list. + If mask&MASK_STDVIEWMODEL then the default view model will also be added. */ + +#endif +#if defined(CSQC) || defined(MENU) +void(entity ent) addentity = #302; /* + Copies the entity fields into a new rentity for later rendering via addscene. */ + +void(entity ent, vector lightdir, vector lightavg, vector lightrange, int reserved1=0,void*reserved2=0) addentity_lighting = #0:addentity_lighting; /* + Copies the entity fields into a new rentity for later rendering via addscene, but with explicit lighting info. */ + +#endif +#ifdef CSQC +void(entity ent) removeentity = #0:removeentity; /* + Undoes all addentities added to the scene from the given entity, without removing ALL entities (useful for splitscreen/etc, readd modified versions as desired). */ + +typedef float vec2[2]; +typedef float vec3[3]; +typedef float vec4[4]; +typedef struct trisoup_simple_vert_s {vec3 xyz;vec2 st;vec4 rgba;} trisoup_simple_vert_t; +void(string texturename, int flags, struct trisoup_simple_vert_s *verts, int *indexes, int numindexes) addtrisoup_simple = #0:addtrisoup_simple; /* + Adds the specified trisoup into the scene as additional geometry. This permits caching geometry to reduce builtin spam. Indexes are a triangle list (so eg quads will need 6 indicies to form two triangles). NOTE: this is not going to be a speedup over polygons if you're still generating lots of new data every frame. */ + +#endif +#if defined(CSQC) || defined(MENU) +#define setviewprop setproperty +float(float property, ...) setproperty = #303; /* + Allows you to override default view properties like viewport, fov, and whether the engine hud will be drawn. Different VF_ values have slightly different arguments, some are vectors, some floats. */ + +void() renderscene = #304; /* + Draws all entities, polygons, and particles on the rentity list (which were added via addentities or addentity), using the various view properties set via setproperty. There is no ordering dependancy. + The scene must generally be cleared again before more entities are added, as entities will persist even over to the next frame. + You may call this builtin multiple times per frame, but should only be called from CSQC_UpdateView. */ + +#endif +#ifdef CSQC +float(vector org, float radius, vector lightcolours, optional float style, optional string cubemapname, optional float pflags) dynamiclight_add = #305; /* + Adds a temporary dlight, ready to be drawn via addscene. Cubemap orientation will be read from v_forward/v_right/v_up. */ + +#endif +void(string texturename, optional float flags, optional float is2d) R_BeginPolygon = #306; /* + Specifies the shader to use for the following polygons, along with optional flags. + If is2d, the polygon will be drawn as soon as the EndPolygon call is made, rather than waiting for renderscene. This allows complex 2d effects. */ + +void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex = #307; /* + Specifies a polygon vertex with its various properties. */ + +void() R_EndPolygon = #308; /* + Ends the current polygon. At least 3 verticies must have been specified. You do not need to call beginpolygon again if you wish to draw another polygon with the same shader. */ + +#ifdef CSQC +void(float radius, vector texcoordbias) R_EndPolygonRibbon = #0:R_EndPolygonRibbon; /* + Ends the current primitive and duplicates each vertex sideways into a ribbon. The texcoordbias will be added to each duplicated vertex allowing for regular 2d textures. At least 2 verticies must have been specified. You do not need to call beginpolygon again if you wish to draw another polygon with the same shader. */ + +#endif +#if defined(CSQC) || defined(MENU) +#define getviewprop getproperty +__variant(float property) getproperty = #309; /* + Retrieve a currently-set (typically view) property, allowing you to read the current viewport or other things. Due to cheat protection, certain values may be unretrievable. */ + +#endif +#ifdef CSQC +vector (vector v) unproject = #310; /* + Transform a 2d screen-space point (with depth) into a 3d world-space point, according the various origin+angle+fov etc settings set via setproperty. */ + +vector (vector v) project = #311; /* + Transform a 3d world-space point into a 2d screen-space point, according the various origin+angle+fov etc settings set via setproperty. */ + +#endif +#if defined(CSQC) || defined(MENU) +float(vector pos, vector size, float alignflags, string text) drawtextfield = #0:drawtextfield; /* + Draws a multi-line block of text, including word wrapping and alignment. alignflags bits are RTLB, typically 3. Returns the total number of lines. */ + +#endif +#ifdef CSQC +void(float width, vector pos1, vector pos2, vector rgb, float alpha, optional float drawflag) drawline = #315; /* + Draws a 2d line between the two 2d points. */ + +float(string name) iscachedpic = #316; /* + Checks to see if the image is currently loaded. Engines might lie, or cache between maps. */ + +string(string name, optional float flags) precache_pic = #317; /* + Forces the engine to load the named image. Flags are a bitmask of the PRECACHE_PIC_* flags. */ + +#endif +#if defined(CSQC) || defined(MENU) +void(string imagename, int width, int height, void *pixeldata, optional int datasize, optional int format) r_uploadimage = #0:r_uploadimage; /* Part of FTE_CSQC_RAWIMAGES + Updates a texture with the specified rgba data (uploading it to the gpu). Will be created if needed. If datasize is specified then the image is decoded (eg .ktx or .dds data) instead of being raw R8G8B8A data. You'll typically want shaderforname to also generate a shader to use the texture. */ + +int*(string filename, __out int width, __out int height, __out int format) r_readimage = #0:r_readimage; /* Part of FTE_CSQC_RAWIMAGES + Reads and decodes an image from disk, providing raw R8G8B8A8 pixel data. Should not be used for dds or ktx etc formats. Returns __NULL__ if the image could not be read for any reason. Use memfree to free the data once you're done with it. */ + +#endif +#ifdef CSQC +#define draw_getimagesize drawgetimagesize +vector(string picname) drawgetimagesize = #318; /* + Returns the dimensions of the named image. Images specified with .lmp should give the original .lmp's dimensions even if texture replacements use a different resolution. WARNING: this function may be slow if used without or directly after its initial precache_pic. */ + +void(string name) freepic = #319; /* + Tells the engine that the image is no longer needed. The image will appear to be new the next time its needed. */ + +string(string modelname, int frame, float frametime) spriteframe = #0:spriteframe; /* + Obtains a suitable shader name to draw a sprite's shader via drawpic/R_BeginPolygon/etc, instead of needing to create a scene. */ + +float(vector position, float character, vector size='8 8', vector rgb='1 1 1', float alpha=1, optional float drawflag=0) drawcharacter = #320; /* + Draw the given quake character at the given position. + If flag&4, the function will consider the char to be a unicode char instead (or display as a ? if outside the 32-127 range). + size should normally be something like '8 8 0'. + rgb should normally be '1 1 1' + alpha normally 1. + Software engines may assume the named defaults. + Note that ALL text may be rescaled on the X axis due to variable width fonts. The X axis may even be ignored completely. */ + +float(vector position, string text, vector size, vector rgb, float alpha, optional float drawflag) drawrawstring = #321; /* + Draws the specified string without using any markup at all, even in engines that support it. + If UTF-8 is globally enabled in the engine, then that encoding is used (without additional markup), otherwise it is raw quake chars. + Software engines may assume a size of '8 8 0', rgb='1 1 1', alpha=1, flag&3=0, but it is not an error to draw out of the screen. */ + +float(vector position, string pic, vector size, vector rgb='1 1 1', float alpha=1, optional float drawflag=0) drawpic = #322; /* + Draws an shader within the given 2d screen box. Software engines may omit support for rgb+alpha, but must support rescaling, and must clip to the screen without crashing. */ + +float(vector position, vector size, vector rgb, float alpha, optional float drawflag) drawfill = #323; /* + Draws a solid block over the given 2d box, with given colour, alpha, and blend mode (specified via flags). + flags&3=0 simple blend. + flags&3=1 additive blend */ + +void(float x, float y, float width, float height) drawsetcliparea = #324; /* + Specifies a 2d clipping region (aka: scissor test). 2d draw calls will all be clipped to this 2d box, the area outside will not be modified by any 2d draw call (even 2d polygons). */ + +void(void) drawresetcliparea = #325; /* + Reverts the scissor/clip area to the whole screen. */ + +float(vector position, string text, vector size='8 8', vector rgb='1 1 1', float alpha=1, float drawflag=0) drawstring = #326; /* + Draws a string, interpreting markup and recolouring as appropriate. */ + +float(string text, float usecolours, vector fontsize='8 8') stringwidth = #327; /* + Calculates the width of the screen in virtual pixels. If usecolours is 1, markup that does not affect the string width will be ignored. Will always be decoded as UTF-8 if UTF-8 is globally enabled. + If the char size is not specified, '8 8 0' will be assumed. */ + +void(vector pos, vector sz, string pic, vector srcpos, vector srcsz, vector rgb, float alpha, optional float drawflag) drawsubpic = #328; /* + Draws a rescaled subsection of an image to the screen. */ + +#endif +#if defined(CSQC) || defined(MENU) +void(vector pivot, vector mins, vector maxs, string pic, vector rgb, float alpha, float angle) drawrotpic = #0:drawrotpic; /* + Draws an image rotating at the pivot. To rotate in the center, use mins+maxs of half the size with mins negated. Angle is in degrees. */ + +void(vector pivot, vector mins, vector maxs, string pic, vector txmin, vector txsize, vector rgb, vector alphaandangles) drawrotsubpic = #0:drawrotsubpic; /* + Overcomplicated draw function for over complicated people. Positions follow drawrotpic, while texture coords follow drawsubpic. Due to argument count limitations in builtins, the alpha value and angles are combined into separate fields of a vector (tip: use fteqcc's [alpha, angle] feature. */ + +#endif +#ifdef CSQC +#define getstati_punf(stnum) (float)(__variant)getstati(stnum) +int(float stnum) getstati = #330; /* + Retrieves the full precision of a stat registered as EV_INTEGER. */ + +#define getstatbits getstatf +float(float stnum, optional float firstbit, optional float bitcount) getstatf = #331; /* + Retrieves the numerical value of the given EV_FLOAT stat. If firstbit and bitcount are specified, then this builtin acts as getstati combined with itof, and which should be used for STAT_ITEMS (but not other stats). */ + +string(float stnum) getstats = #332; /* + Retrieves the value of the given EV_STRING stat, as a tempstring. + Older engines may use 4 consecutive integer stats, with a limit of 15 chars (yes, really. 15.), but FTE Quake uses a separate namespace for string stats and has a much higher length limit. */ + +__variant(float playernum, float statnum, float stattype) getplayerstat = #0:getplayerstat; /* + Retrieves a specific player's stat, matching the type specified on the server. This builtin is primarily intended for mvd playback where ALL players are known. Return value matches the specified EV_ stattype. For EV_ENTITY, world will be returned if the entity is not in the pvs, use type-punning with EV_INTEGER to get the entity number if you just want to see if its set. STAT_ITEMS should be queried as an EV_INTEGER on account of runes and items2 being packed into the upper bits. */ + +void(entity e, float mdlindex) setmodelindex = #333; /* + Sets a model by precache index instead of by name. Otherwise identical to setmodel. */ + +#endif +#if defined(CSQC) || defined(SSQC) +string(float mdlindex) modelnameforindex = #334; /* + Retrieves the name of the model based upon a precache index. This can be used to reduce csqc network traffic by enabling model matching (with getmodelindex). */ + +string(float sndindex) soundnameforindex = #0:soundnameforindex; /* + Retrieves the name of the sound based upon a precache index. This can be used to reduce csqc network traffic by enabling sound matching (with getsoundindex). */ + +float(string effectname) particleeffectnum = #335; /* Part of DP_ENT_TRAILEFFECTNUM, FTE_SV_POINTPARTICLES + Precaches the named particle effect. If your effect name is of the form 'foo.bar' then particles/foo.cfg will be loaded by the client if foo.bar was not already defined. + Different engines will have different particle systems, this specifies the QC API only. */ + +void(float effectnum, entity ent, vector start, vector end) trailparticles = #336; /* Part of FTE_SV_POINTPARTICLES + Draws the given effect between the two named points. If ent is not world, distances will be cached in the entity in order to avoid framerate dependancies. The entity is not otherwise used. */ + +void(float effectnum, vector origin, optional vector dir, optional float count) pointparticles = #337; /* Part of FTE_SV_POINTPARTICLES + Spawn a load of particles from the given effect at the given point traveling or aiming along the direction specified. The number of particles are scaled by the count argument. + For regular particles, the dir vector is multiplied by the 'veladd' property (while orgadd will push the particles along it). Decals will use it as a hint to align to the correct surface. In both cases, it should normally be a unit vector, but other lengths will still work. If it has length 0 then FTE will assume downwards. */ + +#endif +#ifdef CSQC +void(string s, ...) cprint = #338; /* + Print into the center of the screen just as ssqc's centerprint would appear. */ + +#endif +#if defined(CSQC) || defined(SSQC) +void(string s, ...) print = #339; /* Part of DP_SV_PRINT + Unconditionally print on the local system's console, even in ssqc (doesn't care about the value of the developer cvar). */ + +#endif +#ifdef CSQC +string(float keynum) keynumtostring = #340; /* + Returns a hunam-readable name for the given keycode, as a tempstring. */ + +#endif +#ifdef MENU +DEP string(float keynum) keynumtostring_csqc = #340; /* + Returns a hunam-readable name for the given keycode, as a tempstring. */ + +#endif +#ifdef CSQC +float(string keyname) stringtokeynum = #341; /* + Looks up the key name in the same way that the bind command would, returning the keycode for that key. */ + +#endif +#ifdef MENU +DEP float(string keyname) stringtokeynum_csqc = #341; /* + Looks up the key name in the same way that the bind command would, returning the keycode for that key. */ + +#endif +#if defined(CSQC) || defined(MENU) +string(float keynum) getkeybind = #342; /* + Returns the current binding for the given key (returning only the command executed when no modifiers are pressed). */ + +void(float usecursor, optional string cursorimage, optional vector hotspot, optional float scale) setcursormode = #343; /* + Pass TRUE if you want the engine to release the mouse cursor (absolute input events + touchscreen mode). Pass FALSE if you want the engine to grab the cursor (relative input events + standard looking). If the image name is specified, the engine will use that image for a cursor (use an empty string to clear it again), in a way that will not conflict with the console. Images specified this way will be hardware accelerated, if supported by the platform/port. */ + +float(float effective) getcursormode = #0:getcursormode; /* + Reports the cursor mode this module previously attempted to use. If 'effective' is true, reports the cursor mode currently active (if was overriden by a different module which has precidence, for instance, or if there is only a touchscreen and no mouse). */ + +#endif +#ifdef CSQC +vector() getmousepos = #344; /* + Nasty convoluted DP extension. Typically returns deltas instead of positions. Use CSQC_InputEvent instead for such things in csqc mods. */ + +#endif +#if defined(CSQC) || defined(MENU) +void(vector newpos) setmousepos = #0:setmousepos; /* + Warps the mouse cursor to the given location. Should normally only be done following setcursormode(TRUE,...). The warp MAY be visible through *_InputEvent, but normally be seen as an IE_ABSMOUSE event anyway. Not all systems support cursor warping (or even cursors), so this is a hint only and you should not depend upon it. */ + +#endif +#ifdef CSQC +float(float inputsequencenum) getinputstate = #345; /* + Looks up an input frame from the log, setting the input_* globals accordingly. + The sequence number range used for prediction should normally be servercommandframe < sequence <= clientcommandframe. + The sequence equal to clientcommandframe will change between input frames. */ + +void(float sens) setsensitivityscaler = #346; /* + Temporarily scales the player's mouse sensitivity based upon something like zoom, avoiding potential cvar saving and thus corruption. */ + +#endif +#if defined(CSQC) || defined(SSQC) +void(entity ent) runstandardplayerphysics = #347; /* + Perform the engine's standard player movement prediction upon the given entity using the input_* globals to describe movement. */ + +#endif +#ifdef CSQC +string(float playernum, string keyname) getplayerkeyvalue = #348; /* + Look up a player's userinfo, to discover things like their name, topcolor, bottomcolor, skin, team, *ver. + Also includes scoreboard info like frags, ping, pl, userid, entertime, as well as voipspeaking and voiploudness. */ + +float(float playernum, string keyname, optional float assumevalue) getplayerkeyfloat = #0:getplayerkeyfloat; /* + Cheaper version of getplayerkeyvalue that avoids the need for so many tempstrings. */ + +int(float playernum, string keyname, optional void *outptr, int size) getplayerkeyblob = #0:getplayerkeyblob; /* Part of FTE_INFOBLOBS + Obtains a copy of the full data blob. Will write up to size bytes but return the full size. Does not null terminate (but memalloc(ret+1) will, if you want to cast the buffer to a string), and the blob may contain embedded nulls. Ignores all special keys, returning only what is actually there. */ + +#endif +#if defined(CSQC) || defined(MENU) +void(float seat, string keyname, string newvalue) setlocaluserinfo = #0:setlocaluserinfo; /* + Change a userinfo key for the specified local player seat, equivelent to the setinfo console command. The server will normally forward the setting to other clients. */ + +string(float seat, string keyname) getlocaluserinfo = #0:getlocaluserinfo; /* + Reads a local userinfo key for the specified local player seat. This is not quite the same as getplayerkeyvalue, due to latency and possible serverside filtering. */ + +void(float seat, string keyname, void *outptr, int size) setlocaluserinfoblob = #0:setlocaluserinfoblob; /* Part of FTE_INFOBLOBS + Sets the userinfo key to a blob that may contain nulls etc. Keys with a leading underscore will be visible to only the server (for user-specific binary settings). */ + +int(float seat, string keyname, void *outptr, int maxsize) getlocaluserinfoblob = #0:getlocaluserinfoblob; /* Part of FTE_INFOBLOBS + Obtains a copy of the full data blob. Will write up to size bytes but return the full size. Does not null terminate (but memalloc(ret+1) will, if you want to cast the buffer to a string), and the blob may contain embedded nulls. Ignores all special keys, returning only what is actually there. */ + +#endif +#ifdef SSQC +int(string keyname, optional void *outptr, int size) getlocalinfo = #0:getlocalinfo; /* + Obtains a copy of a data blob (with spaces) from the server's private localinfo. Will write up to size bytes and return the actual size. Does not null terminate (but memalloc(ret+1) will, if you want to cast the buffer to a string), and the blob may contain embedded nulls. Ignores all special keys, returning only what is actually there. */ + +void(string keyname, optional void *outptr, int size) setlocalinfo = #0:setlocalinfo; /* + Changes the server's private localinfo. This data will be available for the following map, and will *usually* reload with saved games. */ + +#endif +#if defined(CSQC) || defined(MENU) +float() isdemo = #349; /* + Returns if the client is currently playing a demo or not. Returns 2 when playing an mvd (where other player's stats can be queried, or the pov can be changed freely). */ + +#endif +#ifdef CSQC +float() isserver = #350; /* + Returns non-zero whenever the local console can directly affect the server (ie: listen servers or single-player). Compat note: DP returns 0 for single-player. */ + +void(vector origin, vector forward, vector right, vector up, optional float reverbtype) SetListener = #351; /* + Sets the position of the view, as far as the audio subsystem is concerned. This should be called once per CSQC_UpdateView as it will otherwise revert to default. For reverbtype, see setup_reverb or treat as 'underwater'. */ + +typedef struct { + float flDensity; + float flDiffusion; + float flGain; + float flGainHF; + float flGainLF; + float flDecayTime; + float flDecayHFRatio; + float flDecayLFRatio; + float flReflectionsGain; + float flReflectionsDelay; + vector flReflectionsPan; + float flLateReverbGain; + float flLateReverbDelay; + vector flLateReverbPan; + float flEchoTime; + float flEchoDepth; + float flModulationTime; + float flModulationDepth; + float flAirAbsorptionGainHF; + float flHFReference; + float flLFReference; + float flRoomRolloffFactor; + int iDecayHFLimit; +} reverbinfo_t; +void(float reverbslot, reverbinfo_t *reverbinfo, int sizeofreverinfo_t) setup_reverb = #0:setup_reverb; /* Part of FTE_CSQC_REVERB + Reconfigures a reverb slot for weird effects. Slot 0 is reserved for no effects. Slot 1 is reserved for underwater effects. Reserved slots will be reinitialised on snd_restart, but can otherwise be changed. These reverb slots can be activated with SetListener. Note that reverb will currently only work when using OpenAL. */ + +#endif +void(string cmdname) registercommand = #352; /* + Register the given console command, for easy console use. + Console commands that are later used will invoke CSQC_ConsoleCommand/m_consolecommand/ConsoleCmd according to module. */ + +float(entity ent) wasfreed = #353; /* + Quickly check to see if the entity is currently free. This function is only valid during the half-second non-reuse window, after that it may give bad results. Try one second to make it more robust. */ + +#if defined(CSQC) || defined(SSQC) +string(string key) serverkey = #354; /* + Look up a key in the server's public serverinfo string. If the key contains binary data then it will be truncated at the first null. */ + +float(string key, optional float assumevalue) serverkeyfloat = #0:serverkeyfloat; /* + Version of serverkey that returns the value as a float (which avoids tempstrings). */ + +int(string key, optional void *ptr, int maxsize) serverkeyblob = #0:serverkeyblob; /* Part of FTE_INFOBLOBS + Version of serverkey that returns data as a blob (ie: binary data that may contain nulls). Returns the full blob size, even if truncated (pass maxsize=0 to query required storage). */ + +#endif +#ifdef SSQC +void(string key, void *ptr, optional int size) setserverkey = #0:setserverkey; /* + Changes the server's serverinfo. */ + +#endif +#ifdef CSQC +string(optional string resetstring) getentitytoken = #355; /* + Grab the next token in the map's entity lump. + If resetstring is not specified, the next token will be returned with no other sideeffects. + If empty, will reset from the map before returning the first token, probably {. + If not empty, will tokenize from that string instead. + Always returns tempstrings. */ + +#endif +#if defined(CSQC) || defined(MENU) +float(string s) findfont = #356; /* Part of DP_GFX_FONTS + Looks up a named font slot. Matches the actual font name as a last resort. */ + +float(string fontname, string fontmaps, string sizes, float slot, optional float fix_scale, optional float fix_voffset) loadfont = #357; /* Part of DP_GFX_FONTS + too convoluted for me to even try to explain correct usage. Try drawfont = loadfont("", "cour", "16", -1, 0, 0); to switch to the courier font (optimised for 16 virtual pixels high) ('cour' requires mscorefonts installed in linux). Additionally you can add "outline=1" as an extra token in the sizes string, to have more readable outlined fonts. */ + +#endif +#ifdef CSQC +void(string evname, string evargs, ...) sendevent = #359; /* + Invoke CSEv_evname_evargs in ssqc. evargs must be a string of initials refering to the types of the arguments to pass. v=vector, e=entity(.entnum field is sent), f=float, i=int. 6 arguments max - you can get more if you pack your floats into vectors. */ + +float() readbyte = #360; /* + Reads an unsigned 8-bit value, pair with WriteByte. */ + +float() readchar = #361; /* + Reads a signed 8-bit value. Paired with WriteChar. */ + +float() readshort = #362; /* + Reads a signed 16-bit value. Paired with WriteShort. */ + +float() readlong = #363; /* + Reads a signed 32-bit value. Paired with WriteLong or WriteInt. */ + +float() readcoord = #364; /* + Reads a value matching the unspecified precision written ONLY by WriteCoord. */ + +float() readangle = #365; /* + Reads a value matching the unspecified precision written ONLY by WriteAngle. */ + +string() readstring = #366; /* + Reads a null-terminated string. */ + +float() readfloat = #367; /* + Reads a float without any truncation nor conversions. Data MUST have originally been written with WriteFloat. */ + +__double() readdouble = #0:readdouble; /* + Reads a double-precision float without any truncation nor conversions. Data MUST have originally been written with WriteDouble. */ + +int() readint = #0:readint; /* + Reads a 32bit int without any conversions to float, otherwise interchangable with readlong. */ + +__int64() readint64 = #0:readint64; /* + Reads a 64bit signed int. Paired with WriteInt64. */ + +__uint64() readuint64 = #0:readuint64; /* + Reads a 64bit unsigned int. Paired with WriteUInt64. */ + +float() readentitynum = #368; /* + Reads the serverside index of an entity, paired with WriteEntity. There may be nothing else known about the entity yet, so the result typically needs to be saved as-is and re-looked up each frame. This can be done via getentity(NUM, GE_*) for non-csqc ents, or findentity(world,entnum,NUM) - both of which can fail due to latency. */ + +float(string modelname, float(float isnew) updatecallback, float flags) deltalisten = #371; /* + Specifies a per-modelindex callback to listen for engine-networking entity updates. Such entities are automatically interpolated by the engine (unless flags specifies not to). + The various standard entity fields will be overwritten each frame before the updatecallback function is called. */ + +float(vector org, float radius, vector rgb) dynamiclight_spawnstatic = #0:dynamiclight_spawnstatic; /* + Creates a static persistent light at the given position with the specified colour. Additional properties must be set via dynamiclight_set. */ + +__variant(float lno, float fld) dynamiclight_get = #372; /* + Retrieves a property from the given dynamic/rt light. Return type depends upon the light field requested. */ + +void(float lno, float fld, __variant value) dynamiclight_set = #373; /* + Changes a property on the given dynamic/rt light. Value type depends upon the light field to be changed. */ + +string(float efnum, float body) particleeffectquery = #374; /* + Retrieves either the name or the body of the effect with the given number. The effect body is regenerated from internal state, and can be changed before being reapplied via the localcmd builtin. */ + +void(string shadername, vector origin, vector up, vector side, vector rgb, float alpha) adddecal = #375; /* + Adds a temporary clipped decal shader to the scene, centered at the given point with given orientation. Will be drawn by the next renderscene call, and freed by the next clearscene call. */ + +#endif +#if defined(CSQC) || defined(MENU) +void(entity e, string skinfilename, optional string skindata) setcustomskin = #376; /* Part of FTE_QC_CUSTOMSKINS + Sets an entity's skin overrides to a new skin object. Releases the entities old skin (refcounted). */ + +#endif +#ifdef CSQC +float(string skinfilename, optional string skindata) loadcustomskin = #377; /* Part of FTE_QC_CUSTOMSKINS + Creates a new skin object and returns it. These are custom per-entity surface->shader lookups. The skinfilename/data should be in .skin format: + surfacename,shadername - makes the named surface use the named shader (legacy format for compat with q3) + replace "surfacename" "shadername" - non-legacy equivalent. + qwskin "foo" - use an unmodified quakeworld player skin (including crop+repalette rules) + q1lower 0xff0000 - specify an override for the entity's lower colour, in this case to red + q1upper 0x0000ff - specify an override for the entity's lower colour, in this case to blue + compose "surfacename" "shader" "imagename@x,y:w,h$s,t,s2,t2?r,g,b,a" - compose a skin texture from multiple images. + The texture is determined to be sufficient to hold the first named image, additional images can be named as extra tokens on the same line. + Use a + at the end of the line to continue reading image tokens from the next line also, the named shader must use 'map $diffuse' to read the composed texture (compatible with the defaultskin shader). Must be matched with a releasecustomskin call later, and is pointless without applycustomskin. */ + +void(entity e, float skinobj) applycustomskin = #378; /* Part of FTE_QC_CUSTOMSKINS + Updates the entity's custom skin (refcounted). */ + +void(float skinobj) releasecustomskin = #379; /* Part of FTE_QC_CUSTOMSKINS + Lets the engine know that the skin will no longer be needed. Thanks to refcounting any ents with the skin already applied will retain their skin until later changed. It is valid to destroy a skin just after applying it to an ent in the same function that it was created in, as the skin will only be destroyed once its refcount rops to 0. */ + +void(float devid, float amp_low, float amp_high, float duration) gp_rumble = #0:gp_rumble; /* + Sends a single rumble event to the game-pad specified in devid. Every time you call this, the previous effect is cancelled out. */ + +void(float devid, float left, float right, float duration) gp_rumbletriggers = #0:gp_rumbletriggers; /* + Makes the analog triggers rumble of the specified game-pad, like gp_rumble() one call cancels out the previous one on the device. */ + +void(float devid, vector color) gp_setledcolor = #0:gp_setledcolor; /* + Updates the game-pad LED color. */ + +void(float devid, /*const*/ void *data, int size) gp_settriggerfx = #0:gp_settriggerfx; /* + Sends a specific effect packet to the controller. On the PlayStation 5's DualSense that can adjust the tension on the analog triggers. */ + +#endif +__variant*(int size) memalloc = #384; /* Part of FTE_MEMALLOC + Allocate an arbitary block of memory */ + +void(__variant *ptr) memfree = #385; /* Part of FTE_MEMALLOC + Frees a block of memory that was allocated with memfree */ + +void(__variant *dst, __variant *src, int size) memcpy = #386; /* Part of FTE_MEMALLOC + Copys memory from one location to another */ + +void(__variant *dst, int val, int size) memfill8 = #387; /* Part of FTE_MEMALLOC + Sets an entire block of memory to a specified value. Pretty much always 0. */ + +__variant(__variant *dst, float ofs) memgetval = #388; /* + Looks up the 32bit value stored at a pointer-with-offset. */ + +void(__variant *dst, float ofs, __variant val) memsetval = #389; /* + Changes the 32bit value stored at the specified pointer-with-offset. */ + +__variant*(__variant *base, float ofs) memptradd = #390; /* + Perform some pointer maths. Woo. */ + +float(string s) memstrsize = #0:memstrsize; /* + strlen, except ignores utf-8 */ + +#if defined(CSQC) || defined(MENU) +string(string conname, string field, optional string newvalue) con_getset = #391; /* Part of FTE_CSQC_ALTCONSOLES + Reads or sets a property from a console object. The old value is returned. Iterrate through consoles with the 'next' field. Valid properties: title, name, next, unseen, markup, forceutf8, close, clear, hidden, linecount */ + +void(string conname, string messagefmt, ...) con_printf = #392; /* Part of FTE_CSQC_ALTCONSOLES + Prints onto a named console. */ + +void(string conname, vector pos, vector size, float fontsize) con_draw = #393; /* Part of FTE_CSQC_ALTCONSOLES + Draws the named console. */ + +float(string conname, float inevtype, float parama, float paramb, float paramc) con_input = #394; /* Part of FTE_CSQC_ALTCONSOLES + Forwards input events to the named console. Mouse updates should be absolute only. */ + +void(string newcaption) setwindowcaption = #0:setwindowcaption; /* Part of FTE_CSQC_WINDOWCAPTION + Replaces the title of the game window, as seen when task switching or just running in windowed mode. */ + +float() cvars_haveunsaved = #0:cvars_haveunsaved; /* + Returns true if any archived cvar has an unsaved value. */ + +#endif +float(entity e, float nowreadonly) entityprotection = #0:entityprotection; /* + Changes the protection on the specified entity to protect it from further edits from QC. The return value is the previous setting. Note that this can be used to unprotect the world, but doing so long term is not advised as you will no longer be able to detect invalid entity references. Also, world is not networked, so results might not be seen by clients (or in other words, world.avelocity_y=64 is a bad idea). */ + +#ifdef CSQC +string(vector pos) getlocationname = #0:getlocationname; /* + Looks up the specified position in the current map's .loc file and reports the nearest marked name. */ + +#endif +#ifdef MENU +void(int cliptype) clipboard_get = #0:clipboard_get; /* + Attempts to query the system clipboard. Any pasted text will be returned via Menu_InputEvent */ + +#endif +#if defined(CSQC) || defined(MENU) +void(int cliptype, string text) clipboard_set = #0:clipboard_set; /* + Changes the system clipboard to the specified text. */ + +#endif +#ifdef SSQC +entity(float entnum, optional __out float wasspawned) respawnedict = #0:respawnedict; /* + Acts like edict_num returning a specific entity number, but also marks it as spawned. If it was previously spawned then all of its prior field data will be LOST (you may wish to use wasfreed(edict_num(idx)) to check. */ + +#endif +#if defined(CSQC) || defined(SSQC) +entity(entity from, optional entity to) copyentity = #400; /* Part of DP_QC_COPYENTITY + Copies all fields from one entity to another. */ + +#endif +#ifdef SSQC +__deprecated("No RGB support.") void(entity ent, float colours) setcolor = #401; /* Part of DP_SV_SETCOLOR + Changes a player's colours. The bits 0-3 are the lower/trouser colour, bits 4-7 are the upper/shirt colours. */ + +#endif +#if defined(CSQC) || defined(SSQC) +entity(.string field, string match, optional .entity chainfield) findchain = #402; /* Part of DP_QC_FINDCHAIN*/ +entity(.float fld, float match, optional .entity chainfield) findchainfloat = #403; /* Part of DP_QC_FINDCHAINFLOAT*/ +void(vector org, string modelname, float startframe, float endframe, float framerate) effect = #404; /* Part of DP_SV_EFFECT + Spawns a self-animating sprite */ + +void(vector org, vector dir, float count) te_blood = #405; /* Part of DP_TE_BLOOD*/ +void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower = #406; /* Part of _DP_TE_BLOODSHOWER*/ +void(vector org, vector color) te_explosionrgb = #407; /* Part of DP_TE_EXPLOSIONRGB*/ +void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube = #408; /* Part of DP_TE_PARTICLECUBE*/ +void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain = #409; /* Part of DP_TE_PARTICLERAIN*/ +void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow = #410; /* Part of DP_TE_PARTICLESNOW*/ +void(vector org, vector vel, float howmany) te_spark = #411; /* Part of DP_TE_SPARK*/ +void(vector org) te_gunshotquad = #412; /* Part of _DP_TE_QUADEFFECTS1*/ +void(vector org) te_spikequad = #413; /* Part of _DP_TE_QUADEFFECTS1*/ +void(vector org) te_superspikequad = #414; /* Part of _DP_TE_QUADEFFECTS1*/ +void(vector org) te_explosionquad = #415; /* Part of _DP_TE_QUADEFFECTS1*/ +void(vector org) te_smallflash = #416; /* Part of DP_TE_SMALLFLASH*/ +void(vector org, float radius, float lifetime, vector color) te_customflash = #417; /* Part of DP_TE_CUSTOMFLASH*/ +void(vector org, optional float count) te_gunshot = #418; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ +void(vector org) te_spike = #419; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ +void(vector org) te_superspike = #420; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ +void(vector org) te_explosion = #421; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ +void(vector org) te_tarexplosion = #422; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ +void(vector org) te_wizspike = #423; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ +void(vector org) te_knightspike = #424; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ +void(vector org) te_lavasplash = #425; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ +void(vector org) te_teleport = #426; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ +void(vector org, float color, float colorlength) te_explosion2 = #427; /* Part of DP_TE_STANDARDEFFECTBUILTINS*/ +void(entity own, vector start, vector end) te_lightning1 = #428; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ +void(entity own, vector start, vector end) te_lightning2 = #429; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ +void(entity own, vector start, vector end) te_lightning3 = #430; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ +void(entity own, vector start, vector end) te_beam = #431; /* Part of DP_TE_STANDARDEFFECTBUILTINS*/ +void(vector dir) vectorvectors = #432; /* Part of DP_QC_VECTORVECTORS*/ +void(vector org) te_plasmaburn = #433; /* Part of _DP_TE_PLASMABURN*/ +float(entity e, float s) getsurfacenumpoints = #434; /* Part of DP_QC_GETSURFACE*/ +vector(entity e, float s, float n) getsurfacepoint = #435; /* Part of DP_QC_GETSURFACE*/ +vector(entity e, float s) getsurfacenormal = #436; /* Part of DP_QC_GETSURFACE*/ +string(entity e, float s) getsurfacetexture = #437; /* Part of DP_QC_GETSURFACE*/ +float(entity e, vector p) getsurfacenearpoint = #438; /* Part of DP_QC_GETSURFACE*/ +vector(entity e, float s, vector p) getsurfaceclippedpoint = #439; /* Part of DP_QC_GETSURFACE*/ +#endif +#ifdef MENU +strbuf() buf_create = #440; /* Part of DP_QC_STRINGBUFFERS*/ +void(strbuf bufhandle) buf_del = #441; /* Part of DP_QC_STRINGBUFFERS*/ +float(strbuf bufhandle) buf_getsize = #442; /* Part of DP_QC_STRINGBUFFERS*/ +void(strbuf bufhandle_from, float bufhandle_to) buf_copy = #443; /* Part of DP_QC_STRINGBUFFERS*/ +void(strbuf bufhandle, float sortprefixlen, float backward) buf_sort = #444; /* Part of DP_QC_STRINGBUFFERS*/ +string(strbuf bufhandle, string glue) buf_implode = #445; /* Part of DP_QC_STRINGBUFFERS*/ +string(strbuf bufhandle, float string_index) bufstr_get = #446; /* Part of DP_QC_STRINGBUFFERS*/ +void(strbuf bufhandle, float string_index, string str) bufstr_set = #447; /* Part of DP_QC_STRINGBUFFERS*/ +float(strbuf bufhandle, string str, float ordered) bufstr_add = #448; /* Part of DP_QC_STRINGBUFFERS*/ +void(strbuf bufhandle, float string_index) bufstr_free = #449; /* Part of DP_QC_STRINGBUFFERS*/ +float(string name) iscachedpic = #451; +string(string name, optional float flags) precache_pic = #452; +float(vector position, float character, vector scale, vector rgb, float alpha, optional float flag) drawcharacter = #454; +float(vector position, string text, vector scale, vector rgb, float alpha, optional float flag) drawrawstring = #455; +float(vector position, string pic, vector size, vector rgb, float alpha, optional float flag) drawpic = #456; +float(vector position, vector size, vector rgb, float alpha, optional float flag) drawfill = #457; +void(float x, float y, float width, float height) drawsetcliparea = #458; +void(void) drawresetcliparea = #459; +vector(string picname) drawgetimagesize = #460; +void(float width, vector pos1, vector pos2) drawline = #466; +float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring = #467; +float(string text, float usecolours, vector fontsize='8 8') stringwidth = #468; +void(vector pos, vector sz, string pic, vector srcpos, vector srcsz, vector rgb, float alpha, float flag) drawsubpic = #469; +#endif +#ifdef SSQC +void(entity e, string s) clientcommand = #440; /* Part of KRIMZON_SV_PARSECLIENTCOMMAND*/ +#endif +#if defined(CSQC) || defined(SSQC) +float(string s) tokenize = #441; /* Part of KRIMZON_SV_PARSECLIENTCOMMAND*/ +string(float n) argv = #442; /* Part of KRIMZON_SV_PARSECLIENTCOMMAND*/ +void(entity e, entity tagentity, string tagname) setattachment = #443; /* Part of DP_GFX_QUAKE3MODELTAGS*/ +searchhandle(string pattern, enumflags:float{SB_CASEINSENSITIVE=1<<0,SB_FULLPACKAGEPATH=1<<1,SB_ALLOWDUPES=1<<2,SB_FORCESEARCH=1<<3,SB_MULTISEARCH=1<<4,SB_NAMESORT=1<<5} flags, float quiet, optional string filterpackage) search_begin = #444; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE + initiate a filesystem scan based upon filenames. Be sure to call search_end on the returned handle. SB_FULLPACKAGEPATH interprets the filterpackage arg as a full package path to avoid gamedir ambiguity, equivelent to whichpack's WP_FULLPACKAGEPATH flag. SB_ALLOWDUPES allows returning multiple entries with the same name (but different package, useful with search_fopen). SB_FORCESEARCH requires use of the filterpackage and SB_FULLPACKAGEPATH flag, initiating searches from gamedirs/packages which are not currently active. */ + +void(searchhandle handle) search_end = #445; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE*/ +float(searchhandle handle) search_getsize = #446; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE + Retrieves the number of files that were found. */ + +string(searchhandle handle, float num) search_getfilename = #447; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE + Retrieves name of one of the files that was found by the initial search. */ + +#endif +float(searchhandle handle, float num) search_getfilesize = #0:search_getfilesize; /* Part of FTE_QC_FS_SEARCH_SIZEMTIME + Retrieves the size of one of the files that was found by the initial search. */ + +string(searchhandle handle, float num) search_getfilemtime = #0:search_getfilemtime; /* Part of FTE_QC_FS_SEARCH_SIZEMTIME + Retrieves modification time of one of the files. */ + +string(searchhandle handle, float num) search_getpackagename = #0:search_getpackagename; /* + Retrieves the name of the package containing the file. Search with SB_FULLPACKAGEPATH to see gamedir/package info */ + +filestream(searchhandle handle, float num) search_fopen = #0:search_fopen; /* + Opens the file directly, without getting confused about entries from other packages. Read access only. */ + +#if defined(CSQC) || defined(SSQC) +string(string cvarname) cvar_string = #448; /* Part of DP_QC_CVAR_STRING*/ +entity(entity start, .float fld, float match) findflags = #449; /* Part of DP_QC_FINDFLAGS*/ +entity(.float fld, float match, optional .entity chainfield) findchainflags = #450; /* Part of DP_QC_FINDCHAINFLAGS*/ +float(entity ent, string tagname) gettagindex = #451; /* Part of DP_QC_GETTAGINFO*/ +vector(entity ent, float tagindex) gettaginfo = #452; /* Part of DP_QC_GETTAGINFO + Obtains the current worldspace position+orientation of the bone or tag from the given entity. The return value is the world coord, v_forward, v_right, v_up are also set according to the bone/tag's orientation. */ + +#endif +#ifdef SSQC +void(entity player) dropclient = #453; /* Part of DP_SV_DROPCLIENT*/ +entity() spawnclient = #454; /* Part of DP_SV_BOTCLIENT*/ +float(entity client) clienttype = #455; /* Part of DP_SV_BOTCLIENT*/ +void(float target, string str) WriteUnterminatedString = #456; /* Part of DP_SV_WRITEUNTERMINATEDSTRING*/ +#endif +#if defined(CSQC) || defined(SSQC) +void(vector org, vector vel, float howmany) te_flamejet = #457; /* Part of _DP_TE_FLAMEJET*/ +entity(float entnum) edict_num = #459; /* Part of DP_QC_EDICT_NUM*/ +strbuf() buf_create = #460; /* Part of DP_QC_STRINGBUFFERS*/ +void(strbuf bufhandle) buf_del = #461; /* Part of DP_QC_STRINGBUFFERS*/ +float(strbuf bufhandle) buf_getsize = #462; /* Part of DP_QC_STRINGBUFFERS*/ +void(strbuf bufhandle_from, strbuf bufhandle_to) buf_copy = #463; /* Part of DP_QC_STRINGBUFFERS*/ +void(strbuf bufhandle, float sortprefixlen, float backward) buf_sort = #464; /* Part of DP_QC_STRINGBUFFERS*/ +string(strbuf bufhandle, string glue) buf_implode = #465; /* Part of DP_QC_STRINGBUFFERS*/ +string(strbuf bufhandle, float string_index) bufstr_get = #466; /* Part of DP_QC_STRINGBUFFERS*/ +void(strbuf bufhandle, float string_index, string str) bufstr_set = #467; /* Part of DP_QC_STRINGBUFFERS*/ +float(strbuf bufhandle, string str, float ordered) bufstr_add = #468; /* Part of DP_QC_STRINGBUFFERS*/ +void(strbuf bufhandle, float string_index) bufstr_free = #469; /* Part of DP_QC_STRINGBUFFERS*/ +#endif +float(float s) asin = #471; /* Part of DP_QC_ASINACOSATANATAN2TAN*/ +float(float c) acos = #472; /* Part of DP_QC_ASINACOSATANATAN2TAN*/ +float(float t) atan = #473; /* Part of DP_QC_ASINACOSATANATAN2TAN*/ +float(float c, float s) atan2 = #474; /* Part of DP_QC_ASINACOSATANATAN2TAN*/ +float(float a) tan = #475; /* Part of DP_QC_ASINACOSATANATAN2TAN + Forgive me father, for I have a sunbed and I'm not afraid to use it. */ + +float(string s) strlennocol = #476; /* Part of DP_QC_STRINGCOLORFUNCTIONS + Returns the number of characters in the string after any colour codes or other markup has been parsed. */ + +string(string s) strdecolorize = #477; /* Part of DP_QC_STRINGCOLORFUNCTIONS + Flattens any markup/colours, removing them from the string. */ + +string(float uselocaltime, string format, ...) strftime = #478; /* Part of DP_QC_STRFTIME*/ +float(string s, string separator1, ...) tokenizebyseparator = #479; /* Part of DP_QC_TOKENIZEBYSEPARATOR + Splits up the string using only the specified delimiters/separators. Multiple delimiters can be given, they are each considered equivelent (though should start with the longest if you want to do weird subseparator stuff). + The resulting tokens can be queried via argv (and argv_start|end_index builtins, if you want to determine which of the separators was present between two tokens). + Note that while an input string containing JUST a separator will return 2, a string with no delimiter will return 1, while (in FTE) an empty string will ALWAYS return 0. */ + +string(string s) strtolower = #480; /* Part of DP_QC_STRING_CASE_FUNCTIONS*/ +string(string s) strtoupper = #481; /* Part of DP_QC_STRING_CASE_FUNCTIONS*/ +#if defined(CSQC) || defined(SSQC) +string(string s) cvar_defstring = #482; /* Part of DP_QC_CVAR_DEFSTRING*/ +void(vector origin, string sample, float volume, float attenuation) pointsound = #483; /* Part of DP_SV_POINTSOUND*/ +#endif +string(string search, string replace, string subject) strreplace = #484; /* Part of DP_QC_STRREPLACE*/ +string(string search, string replace, string subject) strireplace = #485; /* Part of DP_QC_STRREPLACE*/ +#if defined(CSQC) || defined(SSQC) +vector(entity e, float s, float n, float a) getsurfacepointattribute = #486; /* Part of DP_QC_GETSURFACEPOINTATTRIBUTE*/ +#endif +#if defined(CSQC) || defined(MENU) +float(string name, optional string initialURI) gecko_create = #487; /* Part of DP_GECKO_SUPPORT + Create a new 'browser tab' shader with the specified name that can then be drawn via drawpic (shader should not already exist - including from map/model textures or disk). In order to function correctly, this builtin depends upon external plugins being available. Use gecko_navigate to navigate it to a page of your choosing. */ + +void(string name) gecko_destroy = #488; /* Part of DP_GECKO_SUPPORT + Destroy a shader. */ + +void(string name, string URI) gecko_navigate = #489; /* Part of DP_GECKO_SUPPORT + Sends a command to the media decoder attached to the specified shader. In the case of a browser decoder, this changes the url that the browser displays. 'cmd:[un]focus' will tell the decoder that it has focus. */ + +float(string name, float key, float eventtype, optional float charcode) gecko_keyevent = #490; /* Part of DP_GECKO_SUPPORT + Send a key event to a media decoder. This applies only to interactive decoders like browsers. */ + +void(string name, float x, float y) gecko_mousemove = #491; /* Part of DP_GECKO_SUPPORT + Sets a media decoder shader's mouse position. Values should be 0-1. */ + +void(string name, float w, float h) gecko_resize = #492; /* Part of DP_GECKO_SUPPORT + Request to resize a media decoder. */ + +vector(string name) gecko_get_texture_extent = #493; /* Part of DP_GECKO_SUPPORT + Retrieves a media decoder current image pixel sizes. */ + +string(string shadname, string propname) gecko_getproperty = #0:gecko_getproperty; /* + Queries the media decoder (especially browser ones) for decoder-specific properties. The cef plugin recognises url, title, status. */ + +#endif +#ifdef CSQC +float(string file, string id) cin_open = #0:cin_open; +void(string id) cin_close = #0:cin_close; +void(string id, float newstate) cin_setstate = #0:cin_setstate; +float(string id) cin_getstate = #0:cin_getstate; +void(string file) cin_restart = #0:cin_restart; +#endif +__deprecated("Use digest_hex") float(float caseinsensitive, string s, ...) crc16 = #494; /* Part of DP_QC_CRC16*/ +float(string name) cvar_type = #495; /* Part of DP_QC_CVAR_TYPE*/ +float() numentityfields = #496; /* Part of DP_QC_ENTITYDATA + Gives the number of named entity fields. Note that this is not the size of an entity, but rather just the number of unique names (ie: vectors use 4 names rather than 3). */ + +float(string fieldname) findentityfield = #0:findentityfield; /* + Find a field index by name. */ + +typedef .__variant field_t; +field_t(float fieldnum) entityfieldref = #0:entityfieldref; /* + Returns a field value that can be directly used to read entity fields. Be sure to validate the type with entityfieldtype before using. */ + +string(float fieldnum) entityfieldname = #497; /* Part of DP_QC_ENTITYDATA + Retrieves the name of the given entity field. */ + +float(float fieldnum) entityfieldtype = #498; /* Part of DP_QC_ENTITYDATA + Provides information about the type of the field specified by the field num. Returns one of the EV_ values. */ + +string(float fieldnum, entity ent) getentityfieldstring = #499; /* Part of DP_QC_ENTITYDATA*/ +float(float fieldnum, entity ent, string s) putentityfieldstring = #500; /* Part of DP_QC_ENTITYDATA*/ +#ifdef SSQC +void(float to, string s, float sz) WritePicture = #501; /* Part of DP_SV_WRITEPICTURE + Encodes the named image across the network as-is adhering to some size limit. In FTE, this simply writes the string and is equivelent to writestring and sz is ignored. WritePicture should be paired with ReadPicture in csqc. */ + +#endif +#ifdef CSQC +string() ReadPicture = #501; /* + Reads a picture that was written by ReadPicture, and returns a name that can be used in drawpic and other 2d drawing functions. In FTE, this acts as a readstring-with-downloadcheck - the image will appear normally once it has been downloaded, but its size may be incorrect until then. */ + +void(float effectindex, entity own, vector org_from, vector org_to, vector dir_from, vector dir_to, float countmultiplier, optional float flags) boxparticles = #502; +#endif +string(string filename, optional enumflags:float{WP_REFERENCEPACKAGE,WP_FULLPACKAGEPATH} flags) whichpack = #503; /* Part of DP_QC_WHICHPACK + Returns the pak file name that contains the file specified. progs/player.mdl will generally return something like 'pak0.pak'. If WP_REFERENCE, clients will automatically be told that the returned package should be pre-downloaded and used, even if allow_download_refpackages is not set. */ + +#ifdef CSQC +__variant(float entnum, float fieldnum) getentity = #504; /* + Looks up fields from non-csqc-visible entities. The entity will need to be within the player's pvs. fieldnum should be one of the GE_ constants. */ + +#endif +string(string in) uri_escape = #510; /* Part of DP_QC_URI_ESCAPE + Uses percent-encoding to encode any bytes in the input string which are not ascii alphanumeric, period, hyphen, or underscore. All other bytes will expand to eg '%20' for a single space char. This encoding scheme is compatible with http and other uris. */ + +string(string in) uri_unescape = #511; /* Part of DP_QC_URI_ESCAPE + Undo any percent-encoding in the input string, hopefully resulting in the same original sequence of bytes (and thus chars too). */ + +float(entity ent) num_for_edict = #512; +#define uri_post uri_get +float(string uril, float id, optional string postmimetype, optional string postdata) uri_get = #513; /* Part of DP_QC_URI_GET, DP_QC_URI_POST + uri_get() gets content from an URL and calls a callback "uri_get_callback" with it set as string; an unique ID of the transfer is returned + returns 1 on success, and then calls the callback with the ID, 0 or the HTTP status code, and the received data in a string + For a POST request, you will typically want the postmimetype set to application/x-www-form-urlencoded. + For a GET request, omit the mime+data entirely. + Consult your webserver/php/etc documentation for best-practise. */ + +float(string str) tokenize_console = #514; /* + Tokenize a string exactly as the console's tokenizer would do so. The regular tokenize builtin became bastardized for convienient string parsing, which resulted in a large disparity that can be exploited to bypass checks implemented in a naive SV_ParseClientCommand function, therefore you can use this builtin to make sure it exactly matches. */ + +float(float idx) argv_start_index = #515; /* + Returns the character index that the tokenized arg started at. */ + +float(float idx) argv_end_index = #516; /* + Returns the character index that the tokenized arg stopped at. */ + +void(strbuf strbuf, string pattern, string antipattern) buf_cvarlist = #517; +string(string cvarname) cvar_description = #518; /* + Retrieves the description of a cvar, which might be useful for tooltips or help files. This may still not be useful. */ + +#if defined(CSQC) || defined(SSQC) +float(optional float timetype) gettime = #519; +#endif +#ifdef CSQC +DEP string(float keynum) keynumtostring_omgwtf = #520; +__deprecated("Does not support modifiers") string(string command, optional float bindmap) findkeysforcommand = #521; /* + Returns a list of keycodes that perform the given console command in a format that can only be parsed via tokenize (NOT tokenize_console). This only and always returns two values - if only one key is actually bound, -1 will be returned. The bindmap argument is listed for compatibility with dp-specific defs, but is ignored in FTE. */ + +#endif +#if defined(CSQC) || defined(MENU) +string(string command, optional float bindmap) findkeysforcommandex = #0:findkeysforcommandex; /* + Returns a list of key bindings in keyname format instead of keynums. Use tokenize to parse. This list may contain modifiers. May return large numbers of keys. */ + +#endif +#if defined(CSQC) || defined(SSQC) +void(string s) loadfromdata = #529; /* + Reads a set of entities from the given string. This string should have the same format as a .ent file or a saved game. Entities will be spawned as required. If you need to see the entities that were created, you should use parseentitydata instead. */ + +void(string s) loadfromfile = #530; /* + Reads a set of entities from the named file. This file should have the same format as a .ent file or a saved game. Entities will be spawned as required. If you need to see the entities that were created, you should use parseentitydata instead. */ + +void(float pause) setpause = #531; /* + Sets whether the server should or should not be paused. This does not affect auto-paused things like when the console is down. */ + +#endif +#ifdef SSQC +float(string mname) precache_vwep_model = #532; /* Part of ZQ_VWEP*/ +#endif +float(float v, optional float base) log = #532; /* + Determines the logarithm of the input value according to the specified base. This can be used to calculate how much something was shifted by. */ + +#ifdef CSQC +float(entity e, float channel, string newsample, float volume, float attenuation, float pitchpct, float flags, float timeoffset) soundupdate = #0:soundupdate; /* + Changes the properties of the current sound being played on the given entity channel. newsample may be empty, and will be ignored in this case. timeoffset is relative to the current position (subtract the result of getsoundtime for absolute positions). Negative volume can be used to stop the sound. Return value is a fractional value based upon the number of audio devices that could be updated - test against TRUE rather than non-zero. */ + +float(entity e, float channel) getsoundtime = #533; /* + Returns the current playback time of the sample on the given entity's channel. Beware CHAN_AUTO (in csqc, channels are not limited by network protocol). */ + +float(entity e, float channel) getchannellevel = #0:getchannellevel; /* + Reports how load the sound's sample is at its current offset. */ + +#endif +#if defined(CSQC) || defined(MENU) +float(string sample) soundlength = #534; /* + Provides a way to query the duration of a sound sample, allowing you to set up a timer to chain samples. */ + +#endif +float(string filename, strbuf bufhandle) buf_loadfile = #535; /* + Appends the named file into a string buffer (which must have been created in advance). The return value merely says whether the file was readable. */ + +float(filestream filehandle, strbuf bufhandle, optional float startpos, optional float numstrings) buf_writefile = #536; /* + Writes the contents of a string buffer onto the end of the supplied filehandle (you must have already used fopen). Additional optional arguments permit you to constrain the writes to a subsection of the stringbuffer. */ + +float(float bufhandle, string match, float matchrule, float startpos, float step) bufstr_find = #537; /* + Looks for the first occurence of the specified string in the buffer, returning its index or -1 on failure. */ + +#ifdef SSQC +float(optional float forcestate) physics_supported = #0:physics_supported; /* + Queries whether rigid body physics is enabled or not. CSQC and SSQC may report different values. If the force argument is specified then the engine will try to activate or release physics (returning the new state, which may fail if plugins or dlls are missing). Note that restarting the physics engine is likely to result in hitches when collision trees get generated. The state may change if a plugin is disabled mid-map. */ + +#endif +#if defined(CSQC) || defined(SSQC) +void(entity e, float physics_enabled) physics_enable = #540; /* + Enable or disable the physics attached to a MOVETYPE_PHYSICS entity. Entities which have been disabled in this way will stop taking so much cpu time. */ + +void(entity e, vector force, vector relative_ofs) physics_addforce = #541; /* + Apply some impulse directional force upon a MOVETYPE_PHYSICS entity. */ + +void(entity e, vector torque) physics_addtorque = #542; /* + Apply some impulse rotational force upon a MOVETYPE_PHYSICS entity. */ + +#endif +#ifdef MENU +void(float dest) setkeydest = #601; +float() getkeydest = #602; +#endif +#if defined(CSQC) || defined(MENU) +void(float trg) setmousetarget = #603; +float() getmousetarget = #604; +#endif +void(.../*, string funcname*/) callfunction = #605; /* + Invokes the named function. The function name is always passed as the last parameter and must always be present. The others are passed to the named function as-is */ + +void(filestream fh, entity e) writetofile = #606; /* + Writes an entity's fields to the named frik_file file handle. */ + +float(string s) isfunction = #607; /* + Returns true if the named function exists and can be called with the callfunction builtin. */ + +#if defined(CSQC) || defined(MENU) +vector(float vidmode, optional float forfullscreen) getresolution = #608; /* + Supposed to query the driver for supported video modes. FTE does not query drivers in this way, nor would it trust drivers anyway. */ + +#endif +#ifdef CSQC +DEP string(float keynum) keynumtostring_menu = #609; +#endif +#ifdef MENU +string(float keynum) keynumtostring = #609; /* + Converts a qscancode key number into a mostly-human-readable name, matching the bind command. */ + +string(string command, optional float bindmap) findkeysforcommand = #610; +#endif +#if defined(CSQC) || defined(MENU) +float(float type) gethostcachevalue = #611; /* Part of FTE_CSQC_SERVERBROWSER*/ +string(float type, float hostnr) gethostcachestring = #612; /* Part of FTE_CSQC_SERVERBROWSER*/ +#endif +float(entity e, string s, optional float offset) parseentitydata = #613; /* + Reads a single entity's fields into an already-spawned entity. s should contain field pairs like in a saved game: {"foo1" "bar" "foo2" "5"}. Returns <=0 on failure, otherwise returns the offset in the string that was read to. */ + +string(entity e) generateentitydata = #0:generateentitydata; /* + Dumps the entities fields into a string which can later be parsed with parseentitydata. */ + +#ifdef MENU +float(string key) stringtokeynum = #614; /* + Returns the qscancode of a key from its name. Names are identical to the bind command. ctrl/shift/alt modifiers are ignored. */ + +#endif +#ifdef CSQC +float(string key) stringtokeynum_menu = #614; +#endif +#if defined(CSQC) || defined(MENU) +void() resethostcachemasks = #615; /* Part of FTE_CSQC_SERVERBROWSER*/ +void(float mask, float fld, string str, float op) sethostcachemaskstring = #616; /* Part of FTE_CSQC_SERVERBROWSER*/ +void(float mask, float fld, float num, float op) sethostcachemasknumber = #617; /* Part of FTE_CSQC_SERVERBROWSER*/ +void() resorthostcache = #618; /* Part of FTE_CSQC_SERVERBROWSER*/ +void(float fld, float descending) sethostcachesort = #619; /* Part of FTE_CSQC_SERVERBROWSER*/ +void(optional float dopurge) refreshhostcache = #620; /* Part of FTE_CSQC_SERVERBROWSER*/ +float(float fld, float hostnr) gethostcachenumber = #621; /* Part of FTE_CSQC_SERVERBROWSER*/ +float(string key) gethostcacheindexforkey = #622; /* Part of FTE_CSQC_SERVERBROWSER*/ +void(string key) addwantedhostcachekey = #623; /* Part of FTE_CSQC_SERVERBROWSER*/ +string() getextresponse = #624; /* Part of FTE_CSQC_SERVERBROWSER*/ +#endif +string(string dnsname, optional float defport) netaddress_resolve = #625; +#if defined(CSQC) || defined(MENU) +string(float n, float prop) getgamedirinfo = #626; /* + Queries properties about an indexed gamedir (or -1 for the current gamedir). Returns null strings when out of bounds. Use the GDDI_* constants for the prop arg. */ + +string(int n, int prop) getpackagemanagerinfo = #0:getpackagemanagerinfo; /* + Queries information about a package from the engine's package manager subsystem. Actions can be taken via the pkg console command. */ + +#endif +string(string fmt, ...) sprintf = #627; /* Part of DP_QC_SPRINTF + 'prints' to a formatted temp-string. Mostly acts as in C, however %d assumes floats (fteqcc has arg checking. Use it.). + type conversions: l=arg is an int, h=arg is a float, and will work as a prefix for any float or int representation. + float representations: d=decimal, e,E=exponent-notation, f,F=floating-point notation, g,G=terse float, c=char code, x,X=hex + other representations: i=int, s=string, S=quoted and marked-up string, v=vector, p=pointer + so %ld will accept an int arg, while %hi will expect a float arg. + entities, fields, and functions will generally need to be printed as ints with %i. */ + +#if defined(CSQC) || defined(SSQC) +float(entity e, float s) getsurfacenumtriangles = #628; +vector(entity e, float s, float n) getsurfacetriangle = #629; +#endif +#if defined(CSQC) || defined(MENU) +float(float key, string bind, optional float bindmap, optional float modifier) setkeybind = #630; +vector() getbindmaps = #631; +float(vector bm) setbindmaps = #632; +#endif +string(string digest, string data, ...) digest_hex = #639; +string(string digest, void *data, int length) digest_ptr = #0:digest_ptr; /* + Calculates the digest of a single contiguous block of memory (including nulls) using the specified hash function. */ + +float(string src, string dst) fcopy = #650; /* + Equivelent to fopen+fread+fwrite+fclose from QC (ie: reads from $gamedir/data/ or $gamedir, but always writes to $gamedir/data/ ) */ + +float(string src, string dst) frename = #651; /* + Renames the file, returning 0 on success. Both paths are relative to the data/ subdir. */ + +float(string fname) fremove = #652; /* + Deletes the named file - path is relative to data/ subdir, like fopen's FILE_WRITE. Returns 0 on success. */ + +float(string fname) fexists = #653; /* + Returns true if it exists inside the default writable path. Use whichpack for greater portability. */ + +float(string path) rmtree = #654; /* + Dangerous, but sandboxed to data/ */ + +#if defined(CSQC) || defined(MENU) +const float K_TAB = 9; +const float K_ENTER = 13; +const float K_ESCAPE = 27; +const float K_SPACE = 32; +const float K_BACKSPACE = 127; +const float K_UPARROW = 128; +const float K_DOWNARROW = 129; +const float K_LEFTARROW = 130; +const float K_RIGHTARROW = 131; +const float K_LALT = 132; +const float K_RALT = -280; +const float K_LCTRL = 133; +const float K_RCTRL = -281; +const float K_LSHIFT = 134; +const float K_RSHIFT = -282; +const float K_F1 = 135; +const float K_F2 = 136; +const float K_F3 = 137; +const float K_F4 = 138; +const float K_F5 = 139; +const float K_F6 = 140; +const float K_F7 = 141; +const float K_F8 = 142; +const float K_F9 = 143; +const float K_F10 = 144; +const float K_F11 = 145; +const float K_F12 = 146; +const float K_INS = 147; +const float K_DEL = 148; +const float K_PGDN = 149; +const float K_PGUP = 150; +const float K_HOME = 151; +const float K_END = 152; +const float K_KP_HOME = 164; +const float K_KP_UPARROW = 165; +const float K_KP_PGUP = 166; +const float K_KP_LEFTARROW = 161; +const float K_KP_5 = 162; +const float K_KP_RIGHTARROW = 163; +const float K_KP_END = 158; +const float K_KP_DOWNARROW = 159; +const float K_KP_PGDN = 160; +const float K_KP_ENTER = 172; +const float K_KP_INS = 157; +const float K_KP_DEL = 167; +const float K_KP_SLASH = 168; +const float K_KP_MINUS = 170; +const float K_KP_PLUS = 171; +const float K_KP_NUMLOCK = 154; +const float K_KP_STAR = 169; +const float K_KP_EQUALS = 173; +const float K_MOUSE1 = 512; +const float K_MOUSE2 = 513; +const float K_MOUSE3 = 514; +const float K_MOUSE4 = 517; +const float K_MOUSE5 = 518; +const float K_MOUSE6 = 519; +const float K_MOUSE7 = 520; +const float K_MOUSE8 = 521; +const float K_MOUSE9 = 522; +const float K_MOUSE10 = 523; +const float K_MWHEELUP = 515; +const float K_MWHEELDOWN = 516; +const float K_LWIN = -274; +const float K_RWIN = -275; +const float K_APP = -276; +const float K_SEARCH = -277; +const float K_POWER = -130; +const float K_VOLUP = -278; +const float K_VOLDOWN = -279; +const float K_JOY1 = 768; +const float K_JOY2 = 769; +const float K_JOY3 = 770; +const float K_JOY4 = 771; +const float K_JOY5 = 772; +const float K_JOY6 = 773; +const float K_JOY7 = 774; +const float K_JOY8 = 775; +const float K_JOY9 = 776; +const float K_JOY10 = 777; +const float K_JOY11 = 778; +const float K_JOY12 = 779; +const float K_JOY13 = 780; +const float K_JOY14 = 781; +const float K_JOY15 = 782; +const float K_JOY16 = 783; +const float K_JOY17 = 784; +const float K_JOY18 = 785; +const float K_JOY19 = 786; +const float K_JOY20 = 787; +const float K_JOY21 = 788; +const float K_JOY22 = 789; +const float K_JOY23 = 790; +const float K_JOY24 = 791; +const float K_JOY25 = 792; +const float K_JOY26 = 793; +const float K_JOY27 = 794; +const float K_JOY28 = 795; +const float K_JOY29 = 796; +const float K_JOY30 = 797; +const float K_JOY31 = 798; +const float K_JOY32 = 799; +const float K_AUX1 = 800; +const float K_AUX2 = 801; +const float K_AUX3 = 802; +const float K_AUX4 = 803; +const float K_AUX5 = 804; +const float K_AUX6 = 805; +const float K_AUX7 = 806; +const float K_AUX8 = 807; +const float K_AUX9 = 808; +const float K_AUX10 = 809; +const float K_AUX11 = 810; +const float K_AUX12 = 811; +const float K_AUX13 = 812; +const float K_AUX14 = 813; +const float K_AUX15 = 814; +const float K_AUX16 = 815; +const float K_PAUSE = 153; +const float K_PRINTSCREEN = 174; +const float K_CAPSLOCK = 155; +const float K_SCROLLLOCK = 156; +const float K_SEMICOLON = 59; +const float K_PLUS = 43; +const float K_MINUS = 45; +const float K_APOSTROPHE = 39; +const float K_QUOTES = 34; +const float K_TILDE = 126; +const float K_BACKQUOTE = 96; +const float K_BACKSLASH = 92; +const float K_GP_A = 826; +const float K_GP_B = 827; +const float K_GP_X = 828; +const float K_GP_Y = 829; +const float K_GP_LSHOULDER = 824; +const float K_GP_RSHOULDER = 825; +const float K_GP_LTRIGGER = 830; +const float K_GP_RTRIGGER = 831; +const float K_GP_BACK = 821; +const float K_GP_START = 820; +const float K_GP_LTHUMB = 822; +const float K_GP_RTHUMB = 823; +const float K_GP_DPAD_UP = 816; +const float K_GP_DPAD_DOWN = 817; +const float K_GP_DPAD_LEFT = 818; +const float K_GP_DPAD_RIGHT = 819; +const float K_GP_GUIDE = -238; +const float K_GP_SHARE = -248; +const float K_GP_PADDLE1 = -249; +const float K_GP_PADDLE2 = -250; +const float K_GP_PADDLE3 = -251; +const float K_GP_PADDLE4 = -252; +const float K_GP_TOUCHPAD = -253; +const float K_GP_UNKNOWN = -264; +const float K_GP_LTHUMB_UP = 832; +const float K_GP_LTHUMB_DOWN = 833; +const float K_GP_LTHUMB_LEFT = 834; +const float K_GP_LTHUMB_RIGHT = 835; +const float K_GP_RTHUMB_UP = 836; +const float K_GP_RTHUMB_DOWN = 837; +const float K_GP_RTHUMB_LEFT = 838; +const float K_GP_RTHUMB_RIGHT = 839; +#endif +#ifdef _ACCESSORS +accessor strbuf : float +{ + inline get float asfloat[float idx] = {return stof(bufstr_get(this, idx));}; + inline set float asfloat[float idx] = {bufstr_set(this, idx, ftos(value));}; + get string[float] = bufstr_get; + set string[float] = bufstr_set; + get float length = buf_getsize; +}; +accessor searchhandle : float +{ + get string[float] = search_getfilename; + get float length = search_getsize; +}; +accessor hashtable : float +{ + inline get vector v[string key] = {return hash_get(this, key, '0 0 0', EV_VECTOR);}; + inline set vector v[string key] = {hash_add(this, key, value, HASH_REPLACE|EV_VECTOR);}; + inline get string s[string key] = {return hash_get(this, key, "", EV_STRING);}; + inline set string s[string key] = {hash_add(this, key, value, HASH_REPLACE|EV_STRING);}; + inline get float f[string key] = {return hash_get(this, key, 0.0, EV_FLOAT);}; + inline set float f[string key] = {hash_add(this, key, value, HASH_REPLACE|EV_FLOAT);}; + inline get __variant[string key] = {return hash_get(this, key, __NULL__);}; + inline set __variant[string key] = {hash_add(this, key, value, HASH_REPLACE);}; +}; +accessor infostring : string +{ + get string[string] = infoget; + inline set& string[string fld] = {this = infoadd(this, fld, value);}; +}; +accessor filestream : float +{ + get string = fgets; + inline set string = {fputs(this,value);}; +}; +#endif +accessor jsonnode : json_t +{ + inline get json_type_e type = json_get_value_type; + inline get string s = json_get_string; + inline get float f = json_get_float; + inline get __int i = json_get_integer; + inline get __int length = json_get_length; + inline get jsonnode a[__int key] = json_get_child_at_index; + inline get jsonnode[string key] = json_find_object_child; + inline get string name = json_get_name; +}; +#undef DEP_CSQC +#undef FTEDEP +#undef DEP +#pragma noref 0 + +typedef enum +{ + false, + true +} bool; diff --git a/src/shared/global.h b/src/shared/global.h index 748b3f57..360a8d97 100644 --- a/src/shared/global.h +++ b/src/shared/global.h @@ -172,3 +172,22 @@ _InitEnd(void) /** Calls a function (with parameters) in a new thread. */ #define thread(x) if (fork()) { x; abort(); } + +#define STRING_SET(x) ((x != __NULL__) && (x != "")) + +bool +fileExists(string filePath) +{ + if (filePath != "") /* not empty */ + if not(whichpack(filePath)) /* not present on disk */ + return false; + + return true; +} + +/* other parts of shared to include */ + + +#include "teams.h" +#include "events.h" +#include "flags.h" diff --git a/src/shared/include.src b/src/shared/include.src index 86f65fe6..79c38f9f 100644 --- a/src/shared/include.src +++ b/src/shared/include.src @@ -26,11 +26,13 @@ NSItem.qc NSWeapon.qc NSPortal.qc NSDebris.qc +NSSound.qc NSClient.qc NSClientSpectator.qc pmove_custom.qc cloader.qc sound.qc +NSRagdoll.qc NSClientPlayer.qc player_pmove.qc propdata.qc @@ -43,6 +45,7 @@ util.qc motd.qc entityDef.qc ammo.qc +api.qc ../xr/include.src ../botlib/NSBot.qc #endlist diff --git a/src/shared/input.h b/src/shared/input.h new file mode 100644 index 00000000..0d4622f7 --- /dev/null +++ b/src/shared/input.h @@ -0,0 +1,18 @@ +// Actually used by input_button etc. +#define INPUT_BUTTON0 0x00000001 /* attack 1*/ +#define INPUT_BUTTON2 0x00000002 /* jumping */ +#define INPUT_BUTTON3 0x00000004 /* prone */ +#define INPUT_BUTTON4 0x00000008 /* reload */ +#define INPUT_BUTTON5 0x00000010 /* secondary */ +#define INPUT_BUTTON6 0x00000020 /* use */ +#define INPUT_BUTTON7 0x00000040 /* reserved */ +#define INPUT_BUTTON8 0x00000080 /* crouching */ + +#define INPUT_PRIMARY INPUT_BUTTON0 +#define INPUT_JUMP INPUT_BUTTON2 +#define INPUT_PRONE INPUT_BUTTON3 +#define INPUT_RELOAD INPUT_BUTTON4 +#define INPUT_SECONDARY INPUT_BUTTON6 +#define INPUT_USE INPUT_BUTTON5 /* This can NEVER change. Engine hard-coded. */ +#define INPUT_SPRINT INPUT_BUTTON7 +#define INPUT_CROUCH INPUT_BUTTON8 diff --git a/src/shared/materials.qc b/src/shared/materials.qc index 835f485d..68bf3d09 100644 --- a/src/shared/materials.qc +++ b/src/shared/materials.qc @@ -35,29 +35,6 @@ var bool g_materialsAreLegacy; /* FIXME: world.... sigh, we should box this into a worldspawn class */ .string materials_file; -// Impact types -typedef enum -{ - IMPACT_MELEE, - IMPACT_EXPLOSION, - IMPACT_DEFAULT, - IMPACT_ALIEN, - IMPACT_COMPUTER, - IMPACT_CONCRETE, - IMPACT_DIRT, - IMPACT_FLESH, - IMPACT_FOLIAGE, - IMPACT_GLASS, - IMPACT_GRATE, - IMPACT_METAL, - IMPACT_SAND, - IMPACT_SLOSH, - IMPACT_SNOW, - IMPACT_TILE, - IMPACT_VENT, - IMPACT_WOOD -} impactType_t; - typedef enum { GSMATERIAL_GLASS, @@ -295,57 +272,38 @@ Materials_LoadFromMat(string filename) } } -/** FIXME: all this should be done exclusively in surfaceproperties.qc, however that -is currently server-side only. Make it shared and then we can get rid of this -whole file! */ - /** loads a temporary mapper so we can map letters to class names. */ static void Materials_Mapper_Init(void) { - string sTemp; + NSDict matDecl = NSDict::LoadDeclFromFile("material", "typeinfo/hlmat.decl"); + int tokenCount; int c = 0; - filestream fileLUT; - string spname = ""; - bool inbrace = false; + int lutSize = 0i; - fileLUT = fopen("scripts/surfaceproperties.txt", FILE_READ); - g_hlmlut_count = 0; - - /* count valid entries. */ - if (fileLUT >= 0) { - while ((sTemp = fgets(fileLUT))) { - if (tokenize_console(sTemp) == 2) { - if (argv(0) == "gamematerial") - g_hlmlut_count++; - } - } + if (!matDecl) { + return; } - /* back to the beginning... */ - fseek(fileLUT, 0); - g_hlmlut = memalloc(sizeof(hlmaterials_lut) * g_hlmlut_count); + tokenCount = matDecl.TokenCount(); + g_hlmlut_count = tokenCount / 2; + lutSize = sizeof(hlmaterials_lut) * g_hlmlut_count; + g_hlmlut = memalloc(lutSize); - /* read in the elements */ - if (fileLUT >= 0) { - while ((sTemp = fgets(fileLUT))) { - /* tokenize and just parse this stuff in */ - if (tokenize_console(sTemp) == 2) { - if (argv(0) == "gamematerial") { - g_hlmlut[c].idx = argv(1); - g_hlmlut[c].matclass = spname; - c++; - } - } - - if (argv(0) == "{") - inbrace = true; - else if (argv(0) == "}") - inbrace = false; - else if (inbrace == false) - spname = argv(0); - } + if (!g_hlmlut) { + NSError("Memory allocation failed for %i bytes.", lutSize); + g_hlmlut_count = 0; + remove(matDecl); + return; } + + for (int i = 0; i < tokenCount; i+=2) { + g_hlmlut[c].idx = argv(i); + g_hlmlut[c].matclass = argv(i+1); + c++; + } + + remove(matDecl); } /** takes a mat id and returns a classname */ diff --git a/src/shared/math.h b/src/shared/math.h index 2c8b7c03..ac388375 100644 --- a/src/shared/math.h +++ b/src/shared/math.h @@ -275,4 +275,4 @@ hsvToRGB(float h, float s, float v) } /** @} */ // end of multiprogs, server -#include "math_vector.h" \ No newline at end of file +#include "math_vector.h" diff --git a/src/shared/player_pmove.qc b/src/shared/player_pmove.qc index 1758359c..a6297323 100644 --- a/src/shared/player_pmove.qc +++ b/src/shared/player_pmove.qc @@ -100,8 +100,8 @@ NSClientPlayer::Physics_Crouch(void) if (CanCrouch() && input_buttons & INPUT_CROUCH) { if (!IsCrouching()) { - testMins = g_pmoveVars.GetCrouchMins(); - testMaxs = g_pmoveVars.GetCrouchMaxs(); + testMins = m_pmoveVars.GetCrouchMins(); + testMaxs = m_pmoveVars.GetCrouchMaxs(); if (PMove_IsStuck(this, origin, testMins, testMaxs) == false) { AddVFlags(VFL_CROUCHING); @@ -116,12 +116,12 @@ NSClientPlayer::Physics_Crouch(void) /* if they're going prone mode, we'll have to test that */ if (input_buttons & INPUT_PRONE) { - testMins = g_pmoveVars.GetProneMins(); - testMaxs = g_pmoveVars.GetProneMaxs(); + testMins = m_pmoveVars.GetProneMins(); + testMaxs = m_pmoveVars.GetProneMaxs(); /*printf("Want to prone.\n");*/ } else { - testMins = g_pmoveVars.GetStandingMins(); - testMaxs = g_pmoveVars.GetStandingMaxs(); + testMins = m_pmoveVars.GetStandingMins(); + testMaxs = m_pmoveVars.GetStandingMaxs(); /*printf("Want to stand.\n");*/ } @@ -145,8 +145,8 @@ NSClientPlayer::Physics_Crouch(void) return; if (IsCrouching()) { - mins = g_pmoveVars.GetCrouchMins(); - maxs = g_pmoveVars.GetCrouchMaxs(); + mins = m_pmoveVars.GetCrouchMins(); + maxs = m_pmoveVars.GetCrouchMaxs(); /*printf("State change finished.\n");*/ } else { mins = testMins; @@ -180,8 +180,8 @@ NSClientPlayer::Physics_Prone(void) if (CanProne() && input_buttons & INPUT_PRONE) { if (!IsProne()) { - testMins = g_pmoveVars.GetProneMins(); - testMaxs = g_pmoveVars.GetProneMaxs(); + testMins = m_pmoveVars.GetProneMins(); + testMaxs = m_pmoveVars.GetProneMaxs(); if (PMove_IsStuck(this, origin, testMins, testMaxs) == false) { AddVFlags(VFL_PRONE); @@ -196,12 +196,12 @@ NSClientPlayer::Physics_Prone(void) /* if they're going prone mode, we'll have to test that */ if (input_buttons & INPUT_CROUCH) { - testMins = g_pmoveVars.GetCrouchMins(); - testMaxs = g_pmoveVars.GetCrouchMaxs(); + testMins = m_pmoveVars.GetCrouchMins(); + testMaxs = m_pmoveVars.GetCrouchMaxs(); /*printf("Want to crouch.\n");*/ } else { - testMins = g_pmoveVars.GetStandingMins(); - testMaxs = g_pmoveVars.GetStandingMaxs(); + testMins = m_pmoveVars.GetStandingMins(); + testMaxs = m_pmoveVars.GetStandingMaxs(); /*printf("Want to stand.\n");*/ } @@ -226,8 +226,8 @@ NSClientPlayer::Physics_Prone(void) return; if (IsProne()) { - mins = g_pmoveVars.GetProneMins(); - maxs = g_pmoveVars.GetProneMaxs(); + mins = m_pmoveVars.GetProneMins(); + maxs = m_pmoveVars.GetProneMaxs(); /*printf("State change finished.\n");*/ } else { mins = testMins; @@ -267,7 +267,7 @@ NSClientPlayer::Physics_Jump(void) } else { /* standard jump here */ if (GetFlags() & FL_ONGROUND) - velocity[2] += g_pmoveVars.pm_jumpheight; + velocity[2] += m_pmoveVars.pm_jumpheight; } } @@ -308,11 +308,11 @@ NSClientPlayer::Physics_SetViewParms(void) { /* cheap operations */ if (IsCrouching()) { - view_ofs = g_pmoveVars.GetCrouchViewOffset(); + view_ofs = m_pmoveVars.GetCrouchViewOffset(); } else if (IsProne()) { - view_ofs = g_pmoveVars.GetProneViewOffset(); + view_ofs = m_pmoveVars.GetProneViewOffset(); } else { - view_ofs = g_pmoveVars.GetStandingViewOffset(); + view_ofs = m_pmoveVars.GetStandingViewOffset(); } } @@ -337,7 +337,7 @@ NSClientPlayer::Physics_WaterJump(void) /* there's nothing preventing us from putting our hands up here */ if (trace_fraction == 1.0) { - velocity[2] = g_pmoveVars.pm_waterjumpheight; + velocity[2] = m_pmoveVars.pm_waterjumpheight; AddFlags(FL_WATERJUMP); RemoveFlags(FL_JUMPRELEASED); return; @@ -419,11 +419,11 @@ float NSClientPlayer::Physics_MaxSpeed(void) { float wishSpeed = 0.0f; - float runSpeed = g_pmoveVars.pm_runspeed; - float maxStamina = g_pmoveVars.pm_stamina; - float crouchSpeed = g_pmoveVars.pm_crouchspeed; - float walkSpeed = g_pmoveVars.pm_walkspeed; - float proneSpeed = g_pmoveVars.pm_pronespeed; + float runSpeed = m_pmoveVars.pm_runspeed; + float maxStamina = m_pmoveVars.pm_stamina; + float crouchSpeed = m_pmoveVars.pm_crouchspeed; + float walkSpeed = m_pmoveVars.pm_walkspeed; + float proneSpeed = m_pmoveVars.pm_pronespeed; float speedMod = 1.0f; if (m_activeWeapon) { @@ -432,16 +432,16 @@ NSClientPlayer::Physics_MaxSpeed(void) if (CanSprint() && IsSprinting()) { if (m_flStamina < maxStamina) { - float slowDownThresh = g_pmoveVars.pm_staminathreshold; + float slowDownThresh = m_pmoveVars.pm_staminathreshold; if ((m_flStamina + slowDownThresh) > maxStamina) { float delta = (m_flStamina + slowDownThresh) - maxStamina; /* change maxValue to something between 1.0 and 1.5 */ runSpeed = lerp(runSpeed, walkSpeed, delta/slowDownThresh); } - } + } - wishSpeed = runSpeed; + wishSpeed = (m_flStamina >= maxStamina) ? walkSpeed : runSpeed; } else if (IsCrouching()) { wishSpeed = crouchSpeed; } else if (IsProne()) { @@ -522,12 +522,12 @@ NSClientPlayer::Physics_InputPostMove(void) m_flStamina += input_timelength; } else { float toSubtract = input_timelength; - toSubtract *= g_pmoveVars.pm_staminarate; + toSubtract *= m_pmoveVars.pm_staminarate; m_flStamina = max(0, m_flStamina - toSubtract); } - if (m_flStamina > g_pmoveVars.pm_stamina) { - m_flStamina = g_pmoveVars.pm_stamina; + if (m_flStamina > m_pmoveVars.pm_stamina) { + m_flStamina = m_pmoveVars.pm_stamina; } //printf("stamina: %f\n", m_flStamina); diff --git a/src/shared/pmove.h b/src/shared/pmove.h index 0f551af6..b806e9fc 100644 --- a/src/shared/pmove.h +++ b/src/shared/pmove.h @@ -108,7 +108,9 @@ public: #endif private: + nonvirtual void Refresh(void); nonvirtual void UpdateBoundingBoxes(void); + nonvirtual void LinkToEntity(string declClass); vector m_vecStandingMins; vector m_vecStandingMaxs; @@ -119,6 +121,7 @@ private: vector m_vecNormalViewOffset; vector m_vecCrouchViewOffset; vector m_vecProneViewOffset; + string m_defLink; }; /** The global, shared object containing all currently valid pmove parameters. */ @@ -130,4 +133,4 @@ void PMove_Init(void); void PMoveCustom_RunPlayerPhysics(entity); void PMoveCustom_RunCrouchPhysics(entity); -/** @} */ // end of pmove \ No newline at end of file +/** @} */ // end of pmove diff --git a/src/shared/pmove.qc b/src/shared/pmove.qc index e795479f..30acdcbc 100644 --- a/src/shared/pmove.qc +++ b/src/shared/pmove.qc @@ -189,6 +189,7 @@ separate cvars for overriding their speeds. */ void NSPMoveVars::NSPMoveVars(void) { + m_defLink = __NULL__; } void @@ -225,10 +226,198 @@ NSPMoveVars::UpdateBoundingBoxes(void) } } +void +NSPMoveVars::Refresh(void) +{ + printf("Refreshing pmove Vars %S\n", m_defLink); + + /* global. */ + if (!STRING_SET(m_defLink)) { + UpdateBoundingBoxes(); + return; + } + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "g_gravity"))) + g_gravity = stof(EntityDef_GetKeyValue(m_defLink, "g_gravity")); + else + g_gravity = g_pmoveVars.g_gravity; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_accelerate"))) + pm_accelerate = stof(EntityDef_GetKeyValue(m_defLink, "pm_accelerate")); + else + pm_accelerate = g_pmoveVars.pm_accelerate; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_airaccelerate"))) + pm_airaccelerate = stof(EntityDef_GetKeyValue(m_defLink, "pm_airaccelerate")); + else + pm_airaccelerate = g_pmoveVars.pm_airaccelerate; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_airstepsize"))) + pm_airstepsize = stof(EntityDef_GetKeyValue(m_defLink, "pm_airstepsize")); + else + pm_airstepsize = g_pmoveVars.pm_airstepsize; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_boxcenter"))) + pm_boxcenter = stof(EntityDef_GetKeyValue(m_defLink, "pm_boxcenter")); + else + pm_boxcenter = g_pmoveVars.pm_boxcenter; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_boxwidth"))) + pm_boxwidth = stof(EntityDef_GetKeyValue(m_defLink, "pm_boxwidth")); + else + pm_boxwidth = g_pmoveVars.pm_boxwidth; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_crouchheight"))) + pm_crouchheight = stof(EntityDef_GetKeyValue(m_defLink, "pm_crouchheight")); + else + pm_crouchheight = g_pmoveVars.pm_crouchheight; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_crouchspeed"))) + pm_crouchspeed = stof(EntityDef_GetKeyValue(m_defLink, "pm_crouchspeed")); + else + pm_crouchspeed = g_pmoveVars.pm_crouchspeed; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_crouchviewheight"))) + pm_crouchviewheight = stof(EntityDef_GetKeyValue(m_defLink, "pm_crouchviewheight")); + else + pm_crouchviewheight = g_pmoveVars.pm_crouchviewheight; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_edgefriction"))) + pm_edgefriction = stof(EntityDef_GetKeyValue(m_defLink, "pm_edgefriction")); + else + pm_edgefriction = g_pmoveVars.pm_edgefriction; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_friction"))) + pm_friction = stof(EntityDef_GetKeyValue(m_defLink, "pm_friction")); + else + pm_friction = g_pmoveVars.pm_friction; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_gravity"))) + pm_gravity = stof(EntityDef_GetKeyValue(m_defLink, "pm_gravity")); + else + pm_gravity = g_pmoveVars.pm_gravity; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_jumpheight"))) + pm_jumpheight = stof(EntityDef_GetKeyValue(m_defLink, "pm_jumpheight")); + else + pm_jumpheight = g_pmoveVars.pm_jumpheight; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_maxviewpitch"))) + pm_maxviewpitch = stof(EntityDef_GetKeyValue(m_defLink, "pm_maxviewpitch")); + else + pm_maxviewpitch = g_pmoveVars.pm_maxviewpitch; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_minviewpitch"))) + pm_minviewpitch = stof(EntityDef_GetKeyValue(m_defLink, "pm_minviewpitch")); + else + pm_minviewpitch = g_pmoveVars.pm_minviewpitch; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_noclipaccelerate"))) + pm_noclipaccelerate = stof(EntityDef_GetKeyValue(m_defLink, "pm_noclipaccelerate")); + else + pm_noclipaccelerate = g_pmoveVars.pm_noclipaccelerate; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_noclipspeed"))) + pm_noclipspeed = stof(EntityDef_GetKeyValue(m_defLink, "pm_noclipspeed")); + else + pm_noclipspeed = g_pmoveVars.pm_noclipspeed; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_normalheight"))) + pm_normalheight = stof(EntityDef_GetKeyValue(m_defLink, "pm_normalheight")); + else + pm_normalheight = g_pmoveVars.pm_normalheight; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_normalviewheight"))) + pm_normalviewheight = stof(EntityDef_GetKeyValue(m_defLink, "pm_normalviewheight")); + else + pm_normalviewheight = g_pmoveVars.pm_normalviewheight; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_nospeedcap"))) + pm_nospeedcap = stof(EntityDef_GetKeyValue(m_defLink, "pm_nospeedcap")); + else + pm_nospeedcap = g_pmoveVars.pm_nospeedcap; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_proneheight"))) + pm_proneheight = stof(EntityDef_GetKeyValue(m_defLink, "pm_proneheight")); + else + pm_proneheight = g_pmoveVars.pm_proneheight; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_pronespeed"))) + pm_pronespeed = stof(EntityDef_GetKeyValue(m_defLink, "pm_pronespeed")); + else + pm_pronespeed = g_pmoveVars.pm_pronespeed; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_proneviewheight"))) + pm_proneviewheight = stof(EntityDef_GetKeyValue(m_defLink, "pm_proneviewheight")); + else + pm_proneviewheight = g_pmoveVars.pm_proneviewheight; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_runspeed"))) + pm_runspeed = stof(EntityDef_GetKeyValue(m_defLink, "pm_runspeed")); + else + pm_runspeed = g_pmoveVars.pm_runspeed; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_stamina"))) + pm_stamina = stof(EntityDef_GetKeyValue(m_defLink, "pm_stamina")); + else + pm_stamina = g_pmoveVars.pm_stamina; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_staminarate"))) + pm_staminarate = stof(EntityDef_GetKeyValue(m_defLink, "pm_staminarate")); + else + pm_staminarate = g_pmoveVars.pm_staminarate; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_staminathreshold"))) + pm_staminathreshold = stof(EntityDef_GetKeyValue(m_defLink, "pm_staminathreshold")); + else + pm_staminathreshold = g_pmoveVars.pm_staminathreshold; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_stepsize"))) + pm_stepsize = stof(EntityDef_GetKeyValue(m_defLink, "pm_stepsize")); + else + pm_stepsize = g_pmoveVars.pm_stepsize; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_stopspeed"))) + pm_stopspeed = stof(EntityDef_GetKeyValue(m_defLink, "pm_stopspeed")); + else + pm_stopspeed = g_pmoveVars.pm_stopspeed; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_walkspeed"))) + pm_walkspeed = stof(EntityDef_GetKeyValue(m_defLink, "pm_walkspeed")); + else + pm_walkspeed = g_pmoveVars.pm_walkspeed; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_wateraccelerate"))) + pm_wateraccelerate = stof(EntityDef_GetKeyValue(m_defLink, "pm_wateraccelerate")); + else + pm_wateraccelerate = g_pmoveVars.pm_wateraccelerate; + + if (STRING_SET(EntityDef_GetKeyValue(m_defLink, "pm_waterjumpheight"))) + pm_waterjumpheight = stof(EntityDef_GetKeyValue(m_defLink, "pm_waterjumpheight")); + else + pm_waterjumpheight = g_pmoveVars.pm_waterjumpheight; + + + UpdateBoundingBoxes(); +} + +void +NSPMoveVars::LinkToEntity(string defName) +{ + m_defLink = defName; + Refresh(); + +} + #ifdef SERVER void NSPMoveVars::EvaluateEntity(void) { + /* this is belonging to a decl */ + if (STRING_SET(m_defLink)) { + return; + } + g_gravity = autocvar_g_gravity; pm_accelerate = autocvar_pm_accelerate; pm_airaccelerate = autocvar_pm_airaccelerate; @@ -300,6 +489,11 @@ NSPMoveVars::EvaluateEntity(void) bool NSPMoveVars::SendEntity(entity pvsEnt, float flChanged) { + /* this is belonging to a decl */ + if (STRING_SET(m_defLink)) { + return (false); + } + WriteByte(MSG_ENTITY, ENT_PMOVEVARS); WriteFloat(MSG_ENTITY, flChanged); @@ -380,7 +574,12 @@ NSPMoveVars::ReceiveEntity(float flNew, float flChanged) g_pmoveVars = this; } - UpdateBoundingBoxes(); + printf("Refreshing all pmove vars.\n"); + + for (NSPMoveVars vars = __NULL__;(vars = (NSPMoveVars)find(vars, ::classname, "NSPMoveVars"));) { + vars.Refresh(); + } + } #endif diff --git a/src/shared/pmove_custom.qc b/src/shared/pmove_custom.qc index 41d2bca8..1cdc06fc 100644 --- a/src/shared/pmove_custom.qc +++ b/src/shared/pmove_custom.qc @@ -52,6 +52,7 @@ PMoveCustom_Categorize(void) int contents; bool inladder = false; vector testPos; + vector ladderTestPos; if (self.movetype == MOVETYPE_NOCLIP) return; @@ -80,14 +81,16 @@ PMoveCustom_Categorize(void) self.flags &= ~FL_ONGROUND;*/ /* ladder content testing */ + makevectors(self.v_angle); + ladderTestPos = self.origin + v_forward * 8.0f; int oldhitcontents = self.hitcontentsmaski; - self.hitcontentsmaski = CONTENTBIT_FTELADDER; - tracebox(self.origin, self.mins, self.maxs, self.origin, MOVE_NORMAL, self); + self.hitcontentsmaski = CONTENTBIT_FTELADDER | CONTENTBIT_Q2LADDER; + tracebox(ladderTestPos, self.mins, self.maxs, ladderTestPos, MOVE_NORMAL, self); self.hitcontentsmaski = oldhitcontents; /* if set, you need to directly face the ladder or else you'll fall right off */ #ifdef LADDERFACING - if (trace_endcontentsi & CONTENTBIT_FTELADDER) { + if (trace_endcontentsi & CONTENTBIT_FTELADDER || trace_endcontentsi & CONTENTBIT_Q2LADDER) { /* place the ladder into a virtual space */ vector ladderpos = trace_ent.absmin + (0.5f * (trace_ent.absmax - trace_ent.absmin)); ladderpos[2] = self.origin[2]; @@ -105,7 +108,7 @@ PMoveCustom_Categorize(void) if (inladder) { #else - if (trace_endcontentsi & CONTENTBIT_FTELADDER) { + if (trace_endcontentsi & CONTENTBIT_FTELADDER || trace_endcontentsi & CONTENTBIT_Q2LADDER) { #endif self.vv_flags |= VFL_ONLADDER; } else { diff --git a/src/shared/propdata.qc b/src/shared/propdata.qc index 643e59d8..ae580f4c 100644 --- a/src/shared/propdata.qc +++ b/src/shared/propdata.qc @@ -96,7 +96,31 @@ PropData_ParseField(int i, string keyName, string setValue) g_propdata[i].name = setValue; break; case "base": +#if 0 + /* HACK: This should be loaded much, much later. */ + int baseID = -1i; g_propdata[i].base = setValue; + baseID = PropData_Load(setValue); + + if (baseID != -1) { + g_propdata[i].health = g_propdata[baseID].health; + g_propdata[i].flags = g_propdata[baseID].flags; + g_propdata[i].damage_bullets = g_propdata[baseID].damage_bullets; + g_propdata[i].damage_melee = g_propdata[baseID].damage_melee; + g_propdata[i].damage_explosive = g_propdata[baseID].damage_explosive; + g_propdata[i].explosive_damage = g_propdata[baseID].explosive_damage; + g_propdata[i].explosive_radius = g_propdata[baseID].explosive_radius; + g_propdata[i].breakable_model = g_propdata[baseID].breakable_model; + g_propdata[i].breakable_count = g_propdata[baseID].breakable_count; + g_propdata[i].breakable_skin = g_propdata[baseID].breakable_skin; + g_propdata[i].mass = g_propdata[baseID].mass; + g_propdata[i].damping_linear = g_propdata[baseID].damping_linear; + g_propdata[i].damping_angular = g_propdata[baseID].damping_angular; + g_propdata[i].inertia = g_propdata[baseID].inertia; + g_propdata[i].volume = g_propdata[baseID].volume; + g_propdata[i].surfaceprop = g_propdata[baseID].surfaceprop; + } +#endif break; case "blockLOS": g_propdata[i].flags |= PDFL_BLOCKLOS; @@ -312,10 +336,22 @@ PropData_ForModel(string modelname) return cache; } + /* harsh optimisation. don't attempt to load new propdata after. */ + /*if (time > 1.0f) { + return -1; + }*/ + g_propdata_count++; #ifdef PROPDATA_DYNAMIC g_propdata = (propdata_t *)memrealloc(g_propdata, sizeof(propdata_t), index, g_propdata_count); + + if (!g_propdata) { + NSError("Memory re-allocation failed."); + g_propdata_count = 0; + return -1i; + } + #else if (g_propdata_count >= PROPDATA_MAX) { NSError("PropData_ForModel: Reached PROPDATA_MAX (%d)", PROPDATA_MAX); @@ -347,7 +383,9 @@ PropData_ForModel(string modelname) filePos = fread(fh, (void*)&fileSize, 4i); /* header size, sanity check */ if (fileSize != 16i) { - error("Only .phy files from Source are supported."); + NSError("Only .phy files from Source are supported."); + fclose(fh); + return -1; } filePos = fread(fh, (void*)&phyID, 4i); /* some header id */ @@ -360,8 +398,11 @@ PropData_ForModel(string modelname) //print(sprintf("num fileSum: %i\n", fileSum)); /* HACK: We won't support ragdolls, for now. */ - if (numSolids > 1) + if (numSolids > 1) { + NSError("Only .phy files from Source are supported."); + fclose(fh); return -1; + } /* we skip over all these to get to the bottom of the file */ for (int i = 0i; i < numSolids; i++) { @@ -463,7 +504,7 @@ PropData_ForModel(string modelname) } fclose(fh); - NSError("No type found for %s", modelname); + NSLog("No type found for %s", modelname); return -1; } @@ -475,12 +516,15 @@ PropData_Load(string type) if (!type) return -1; + if (substring(type, 0, 1) == "*") + return -1; + type = strtolower(type); index = (int)hash_get(g_hashpropdata, type, -1); if (index < 0) { - NSError("PropData type %S is not defined.", type); + NSLog("PropData type %S is not defined.", type); return -1; } else { return index; @@ -602,6 +646,8 @@ PropData_Init(void) filestream fh; string line; int index; + int pdMemSize; + int bmMemSize; InitStart(); @@ -630,23 +676,43 @@ PropData_Init(void) } #ifdef PROPDATA_DYNAMIC - /* alocate our stuff */ - g_propdata = (propdata_t *)memalloc(sizeof(propdata_t) * g_propdata_count); - g_breakmodel = (breakModel_t *)memalloc(sizeof(breakModel_t) * g_breakmodel_count); + pdMemSize = sizeof(propdata_t) * g_propdata_count; #else - /* alocate our stuff */ - g_propdata = (propdata_t *)memalloc(sizeof(propdata_t) * PROPDATA_MAX); - g_breakmodel = (breakModel_t *)memalloc(sizeof(breakModel_t) * PROPDATA_MAX); - NSLog("...allocated %d bytes for prop data.", sizeof(propdata_t) * PROPDATA_MAX); - NSLog("...allocated %d bytes for breakmodels.", sizeof(breakModel_t) * PROPDATA_MAX); + pdMemSize = sizeof(propdata_t) * PROPDATA_MAX; #endif + g_propdata = (propdata_t *)memalloc(pdMemSize); + + if (!g_propdata) { + NSError("Memory allocation failed for %i bytes.", pdMemSize); + InitEnd(); + return; + } + +#ifdef PROPDATA_DYNAMIC + bmMemSize = sizeof(breakModel_t) * g_breakmodel_count; +#else + bmMemSize = sizeof(breakModel_t) * PROPDATA_MAX; +#endif + + g_breakmodel = (breakModel_t *)memalloc(bmMemSize); + + if (!g_breakmodel) { + NSError("Memory allocation failed for %i bytes.", bmMemSize); + InitEnd(); + return; + } + + NSLog("...allocated %i bytes for prop data.", pdMemSize); + NSLog("...allocated %i bytes for breakmodels.", bmMemSize); + fseek(fh, 0); while ((line = fgets(fh))) { /* when we found it, quit */ PropData_ParseLine(line); } + fclose(fh); /* now let's precache all of our breakmodel units. @@ -811,12 +877,10 @@ BreakModel_SpawnID(vector smins, vector smaxs, vector dir, float speed, int coun gib.SetSolid(SOLID_NOT); } else { gib.SetMovetype(MOVETYPE_PHYSICS); - gib.SetSolid(SOLID_NOT); + gib.SetSolid(SOLID_CORPSE); gib.mass = 1.0f; gib.friction = 1.0f; - gib.bouncefactor = 0.9f; - gib.bouncestop = 0.1f / cvar("sv_gravity"); - gib.geomtype = GEOMTYPE_TRIMESH; + gib.m_iShape = GEOMTYPE_TRIMESH; gib.ApplyForceOffset(dir * speed, endpos); } diff --git a/src/shared/sentences.qc b/src/shared/sentences.qc index a0d2c18f..a273081f 100644 --- a/src/shared/sentences.qc +++ b/src/shared/sentences.qc @@ -34,6 +34,7 @@ typedef struct #endif var string g_sentences_samplepath; +const string g_sentencesFile = "sound/sentences.txt"; void Sentences_Shutdown(void) @@ -57,10 +58,10 @@ Sentences_Init(void) Sentences_Shutdown(); - fs_sentences = fopen("sound/sentences.txt", FILE_READ); + fs_sentences = fopen(g_sentencesFile, FILE_READ); if (fs_sentences < 0) { - NSError("Missing file sound/sentences.txt"); + NSWarning("No Sentences, missing %S", g_sentencesFile); InitEnd(); return; } diff --git a/src/shared/surfaceproperties.qc b/src/shared/surfaceproperties.qc index ca123360..46fe1927 100644 --- a/src/shared/surfaceproperties.qc +++ b/src/shared/surfaceproperties.qc @@ -85,9 +85,6 @@ SurfData_ParseField(int i, int a) case "fx_bulletimpact": case "part_bulletimpact": g_surfdata[i].m_fxBulletImpact = argv(1); -#ifdef CLIENT - g_surfdata[i].m_fxBulletImpactID = particleeffectnum(g_surfdata[i].m_fxBulletImpact); -#endif break; } } @@ -138,12 +135,12 @@ SurfData_Parse(string line) } } - i++; } /* when we found it, quit */ tokenize_console(t_name); hash_add(g_hashsurfdata, argv(0), (int)i); + i++; braced--; t_name = ""; @@ -352,7 +349,9 @@ SurfData_Init(void) filestream fh; string line; int index; + int args; bool fromManifest = true; + int spMemSize; InitStart(); @@ -388,7 +387,7 @@ SurfData_Init(void) /* first we count all valid entries. yes, this is not how you're meant to parse it, but w/e */ while ((line = fgets(fh))) { - int args = tokenize_console(line); + args = tokenize_console(line); if (args == 2) { if (argv(0) == "file") { @@ -399,7 +398,16 @@ SurfData_Init(void) } /* now that we've counted the valid entries, alocate our stuff */ - g_surfdata = (surfaceData_t *)memalloc(sizeof(surfaceData_t) * g_surfdata_count); + spMemSize = sizeof(surfaceData_t) * g_surfdata_count; + g_surfdata = (surfaceData_t *)memalloc(spMemSize); + + if (!g_surfdata) { + NSError("Memory allocation failed for %i bytes.", spMemSize); + g_surfdata_count = 0; + InitEnd(); + return; + } + g_hashsurfdata = hash_createtab(2, HASH_ADD); /* Internal, defaults. Most of them get overriden by the first entry ('default') */ @@ -425,15 +433,17 @@ SurfData_Init(void) g_surfdata[i].m_sndStrain = ""; g_surfdata[i].m_sndRoll = ""; g_surfdata[i].m_sndBreak = ""; + g_surfdata[i].m_fxBulletImpact = ""; + g_surfdata[i].m_fxBulletImpactID = -1; } + fseek(fh, 0); + if (fromManifest == false) { SurfData_LoadFile("scripts/surfaceproperties.txt"); } else { - fseek(fh, 0); - while ((line = fgets(fh))) { - int args = tokenize_console(line); + args = tokenize_console(line); if (args == 2) { if (argv(0) == "file") { @@ -443,6 +453,58 @@ SurfData_Init(void) } } + fclose(fh); + +#if 1 + for (int i = 1i; i < g_surfdata_count; i++) { + int matID = -1; + + if (!STRING_SET(g_surfdata[i].m_strBase)) { + continue; + } + + matID = SurfData_Load(g_surfdata[i].m_strBase); + + /* ugly inheriting */ + if (matID == -1) { + continue; + } + + //printf("%i inheriting %S from %i\n", i, g_surfdata[i].m_strBase, matID); + + if (g_surfdata[i].m_flMaterial == -1) { + g_surfdata[i].m_flMaterial = g_surfdata[matID].m_flMaterial; + //printf("%i inheriting material %d %d from %i\n", i, g_surfdata[i].m_flMaterial, g_surfdata[matID].m_flMaterial, matID); + } + + if (!STRING_SET(g_surfdata[i].m_sndStepLeft)) + g_surfdata[i].m_sndStepLeft = g_surfdata[matID].m_sndStepLeft; + if (!STRING_SET(g_surfdata[i].m_sndStepRight)) + g_surfdata[i].m_sndStepRight = g_surfdata[matID].m_sndStepRight; + if (!STRING_SET(g_surfdata[i].m_sndBulletImpact)) + g_surfdata[i].m_sndBulletImpact = g_surfdata[matID].m_sndBulletImpact; + if (!STRING_SET(g_surfdata[i].m_sndScrapeRough)) + g_surfdata[i].m_sndScrapeRough = g_surfdata[matID].m_sndScrapeRough; + if (!STRING_SET(g_surfdata[i].m_sndScrapeSoft)) + g_surfdata[i].m_sndScrapeSoft = g_surfdata[matID].m_sndScrapeSoft; + if (!STRING_SET(g_surfdata[i].m_sndImpactHard)) + g_surfdata[i].m_sndImpactHard = g_surfdata[matID].m_sndImpactHard; + if (!STRING_SET(g_surfdata[i].m_sndImpactSoft)) + g_surfdata[i].m_sndImpactSoft = g_surfdata[matID].m_sndImpactSoft; + if (!STRING_SET(g_surfdata[i].m_sndShake)) + g_surfdata[i].m_sndShake = g_surfdata[matID].m_sndShake; + if (!STRING_SET(g_surfdata[i].m_sndStrain)) + g_surfdata[i].m_sndStrain = g_surfdata[matID].m_sndStrain; + if (!STRING_SET(g_surfdata[i].m_sndRoll)) + g_surfdata[i].m_sndRoll = g_surfdata[matID].m_sndRoll; + if (!STRING_SET(g_surfdata[i].m_sndBreak)) + g_surfdata[i].m_sndBreak = g_surfdata[matID].m_sndBreak; + if (!STRING_SET(g_surfdata[i].m_fxBulletImpact)) + g_surfdata[i].m_fxBulletImpact = g_surfdata[matID].m_fxBulletImpact; + + } +#endif + for (int i = 0i; i < g_surfdata_count; i++) { Sound_Precache(g_surfdata[i].m_sndStepLeft); Sound_Precache(g_surfdata[i].m_sndStepRight); @@ -455,6 +517,44 @@ SurfData_Init(void) Sound_Precache(g_surfdata[i].m_sndStrain); Sound_Precache(g_surfdata[i].m_sndRoll); Sound_Precache(g_surfdata[i].m_sndBreak); +#if 1 + /* HACK: HL2 hard-codes these! */ + if (!STRING_SET(g_surfdata[i].m_fxBulletImpact) && g_surfdata[i].m_flMaterial != -1) { + string newFXImpact = ""; + + switch (g_surfdata[i].m_flMaterial) { + case 'C': + case 'T': + newFXImpact = "impact.concrete"; + break; + case 'W': + newFXImpact = "impact.wood"; + break; + case 'D': + newFXImpact = "impact.dirt"; + break; + case 'N': + newFXImpact = "impact.sand"; + break; + case 'A': + newFXImpact = "impact.alien"; + break; + case 'M': + case 'V': + newFXImpact = "impact.metal"; + break; + case 'C': + newFXImpact = "impact.computer"; + break; + } + + g_surfdata[i].m_fxBulletImpact = newFXImpact; + } +#endif + + if (STRING_SET(g_surfdata[i].m_fxBulletImpact)) { + g_surfdata[i].m_fxBulletImpactID = particleeffectnum(g_surfdata[i].m_fxBulletImpact); + } } NSLog("...SurfData initialized with %i entries.", g_surfdata_count); @@ -541,6 +641,11 @@ SurfData_Impact_Parse(void) float impactid = SurfData_GetInfo(matid, SURFDATA_FX_BULLETIMPACTID); Sound_PlayAt(impactorg, impactsfx); + +#if 0 + impactid = particleeffectnum("impact.concrete"); +#endif + pointparticles( impactid, impactorg, normalize(impactang), 1 ); } @@ -564,6 +669,13 @@ SurfData_ImpactID_Parse(void) string impactsfx = SurfData_GetInfo(matid, SURFDATA_SND_BULLETIMPACT); float impactid = SurfData_GetInfo(matid, SURFDATA_FX_BULLETIMPACTID); Sound_PlayAt(impactorg, impactsfx); + + //printf("Prop Impact Receive %i %S %S\n", matid, impactsfx, SurfData_GetInfo(matid, SURFDATA_FX_BULLETIMPACT)); + +#if 0 + impactid = particleeffectnum("impact.concrete"); +#endif + pointparticles( impactid, impactorg, normalize(impactang), 1 ); } #endif @@ -588,8 +700,9 @@ SurfData_Impact(entity e, vector org, vector ang) } else { /* anything with else is a NSurfacePropEntity. */ NSSurfacePropEntity foo = (NSSurfacePropEntity)e; - if (foo.HasSurfaceData() && foo.GetSurfaceData(SURFDATA_MATERIAL) != -1) { - SurfData_ImpactOfType(foo.GetSurfaceData(SURFDATA_MATERIAL), org, ang); + if (foo.HasSurfaceData()) { + SurfData_ImpactOfType(foo.m_iMaterial, org, ang); + //printf("Prop Impact Send %i\n", foo.m_iMaterial); } else { SurfData_Impact_SurfaceParm(e, org, ang); } diff --git a/src/shared/teams.h b/src/shared/teams.h new file mode 100644 index 00000000..f6573fd2 --- /dev/null +++ b/src/shared/teams.h @@ -0,0 +1,8 @@ +/** We basically follow what GMod does. https://wiki.facepunch.com/gmod/Enums/TEAM */ +enum +{ + TEAM_CONNECTING = 0,/**< Set upon ClientConnect. Player is not done joining. */ + /* this is where games can set up whatever they want */ + TEAM_UNASSIGNED = 1001, /**< set on PutClientInServer (first time only */ + TEAM_SPECTATOR = 1002, /**< spectator. can be real (never playable) or fake (see CS, inbetween rounds) */ +}; diff --git a/src/vgui/include.src b/src/vgui/include.src index c426f95d..1ce74d79 100644 --- a/src/vgui/include.src +++ b/src/vgui/include.src @@ -4,6 +4,7 @@ ../vgui/ui.qc ../vgui/ui_control.qc ../vgui/ui_button.qc +../vgui/ui_commandbutton.qc ../vgui/ui_menubutton.qc ../vgui/ui_radio.qc ../vgui/ui_checkbox.qc @@ -18,4 +19,7 @@ ../vgui/ui_listbox.qc ../vgui/ui_textbox.qc ../vgui/ui_tabview.qc +../vgui/ui_progressbar.qc +../vgui/ui_loadingpanel.qc +../vgui/ui_console.qc #endlist diff --git a/src/vgui/ui.qc b/src/vgui/ui.qc index 1d4ee70c..fdaaad43 100644 --- a/src/vgui/ui.qc +++ b/src/vgui/ui.qc @@ -33,6 +33,7 @@ font_s g_fntDefault; var int g_vguiWidgetCount; +int g_lastmousepos[2]; /** @ingroup vgui * @@ -328,7 +329,14 @@ VGUIWidget::HasFlag(int flag) void VGUIWidget::Reposition(void) { + VGUIWidget wNext = this; + do { + wNext = wNext.m_next; + if (wNext) { + wNext.Reposition(); + } + } while (wNext); } void @@ -420,28 +428,80 @@ VGUIWidget::Spawned(void) { } + void UISystem_Init(void) { - /* we support fancier stuff in non-classic mode */ -#ifndef CLASSIC_VGUI string strTemp; - string strUIFile = "scripts/ui_style.txt"; + +#ifdef CLIENT + string strUIFile = "scripts/client_style.txt"; +#else + string strUIFile = "scripts/menu_style.txt"; +#endif + filestream fileUI = fopen(strUIFile, FILE_READ); + if (fileUI < 0) { + strUIFile = "scripts/ui_style.txt"; + fileUI = fopen(strUIFile, FILE_READ); + } + UI_MAINCOLOR = [68,68,68] / 255; + UI_FGCOLOR = [255,255,255] / 255; UI_MAINALPHA = 1.0f; + UI_ROUNDED = false; + UI_NOICONS = false; + UI_HICOLOR = [255,255,255] / 255; + UI_LOCOLOR = [0,0,0] / 255; + UI_BORDERCOLOR = [255,255,255] / 255; + UI_BORDERALPHA = 0 / 255; + UI_FILLCOLOR = [255,255,255] / 255; + UI_HOVERCOLOR = [255,255,255] / 255; + UI_HOVERALPHA = 0; if (fileUI >= 0) { while ((strTemp = fgets(fileUI))) { if (tokenizebyseparator(strTemp, "=") == 2) { switch (argv(0)) { + case "BG_COLOR": case "COLOR": UI_MAINCOLOR = stov(argv(1)) / 255; break; + case "FG_COLOR": + UI_FGCOLOR = stov(argv(1)) / 255; + break; + case "HILIGHT_COLOR": + UI_HICOLOR = stov(argv(1)) / 255; + break; + case "SHADOW_COLOR": + UI_LOCOLOR = stov(argv(1)) / 255; + break; + case "BORDER_COLOR": + UI_BORDERCOLOR = stov(argv(1)) / 255; + break; + case "FILL_COLOR": + UI_FILLCOLOR = stov(argv(1)) / 255; + break; + case "BORDER_ALPHA": + UI_BORDERALPHA = stof(argv(1)) / 255; + break; + case "HOVER_COLOR": + UI_HOVERCOLOR = stov(argv(1)) / 255; + break; + case "HOVER_ALPHA": + UI_HOVERALPHA = stof(argv(1)) / 255; + break; + case "BG_ALPHA": case "ALPHA": UI_MAINALPHA = stof(argv(1)) / 255; break; + case "ROUNDED": + UI_ROUNDED = (bool)stof(argv(1)); + break; + case "NOICONS": + UI_NOICONS = (bool)stof(argv(1)); + break; } } } @@ -449,16 +509,9 @@ UISystem_Init(void) } else { NSError(sprintf("[MENU] Cannot load UI file %s!", strUIFile)); } -#endif Font_Load("fonts/ui.font", g_fntDefault); - precache_pic("textures/ui/steam/icon_radiosel"); - precache_pic("textures/ui/steam/icon_radiounsel"); - precache_pic("textures/ui/steam/icon_checked"); - precache_pic("textures/ui/steam/icon_emptybox"); - precache_pic("textures/ui/steam/icon_down"); - precache_pic("textures/ui/steam/icon_up"); - precache_pic("textures/ui/steam/icon_close"); + } #ifdef CLIENT @@ -484,4 +537,4 @@ UIClass_Spawn(string cname) } #endif -/** @} */ // end of vgui \ No newline at end of file +/** @} */ // end of vgui diff --git a/src/vgui/ui_button.qc b/src/vgui/ui_button.qc index 56a18497..3404e4d0 100644 --- a/src/vgui/ui_button.qc +++ b/src/vgui/ui_button.qc @@ -18,7 +18,8 @@ enumflags { BUTTON_HOVER, BUTTON_DOWN, - BUTTON_LASTACTIVE + BUTTON_LASTACTIVE, + BUTTON_CUSTOMFLAGS }; /* TODO: MOVE THESE INTO VGUIButton! COMPILER NEEDS TO BE FIXED FIRST HOWEVER. */ @@ -97,14 +98,14 @@ void VGUIButton::SetIconColor(vector vecColor) { m_vecIconColor = vecColor; -}; +} void VGUIButton::SetTitle(string strName) { vector newsize = [0.0f, 0.0f, 0.0f]; - m_strTitle = strName; + m_strTitle = sprintf("%s%s", Font_RGBtoHex(UI_FGCOLOR), strName); m_strTitleActive = sprintf("^3%s", m_strTitle); //m_strTitle = sprintf("%s%s", Font_RGBtoHex(UI_MAINCOLOR), strName); drawfont = g_fntDefault.iID; @@ -161,11 +162,12 @@ VGUIButton::GetKeyEquivalent(void) void VGUIButton::Draw(void) { -#ifndef CLASSIC_VGUI VGUITheme theme = GetTheme(); if (m_iFlags & BUTTON_DOWN) { theme.DrawButton(m_parent.m_vecOrigin + m_vecOrigin, m_vecSize, VGUI_STATE_ACTIVE); + } else if (m_iFlags & BUTTON_HOVER) { + theme.DrawButton(m_parent.m_vecOrigin + m_vecOrigin, m_vecSize, VGUI_STATE_HOVER); } else { theme.DrawButton(m_parent.m_vecOrigin + m_vecOrigin, m_vecSize, VGUI_STATE_NORMAL); } @@ -181,63 +183,22 @@ VGUIButton::Draw(void) theme.DrawText(m_parent.m_vecOrigin + m_vecOrigin + [8, 8], keyText, m_vecSize, g_fntDefault); } - if (m_strTitle) { + if (STRING_SET(m_strIcon) && UI_NOICONS == false) { + if (m_iFlags & BUTTON_DOWN) + drawpic(m_parent.m_vecOrigin + m_vecOrigin + [4,4], m_strIcon, m_vecIMGSize, m_vecIconColor * 0.25, 1.0f, 0); + else + drawpic(m_parent.m_vecOrigin + m_vecOrigin + [4,4], m_strIcon, m_vecIMGSize, m_vecIconColor, 1.0f, 0); + + textPadding += m_vecIMGSize[0] + 4; + } + + if (STRING_SET(m_strTitle)) { if (m_iFlags & BUTTON_HOVER) { theme.DrawText(m_parent.m_vecOrigin + m_vecOrigin + [textPadding, 8], m_strTitle, m_vecSize, g_fntDefault); } else { theme.DrawText(m_parent.m_vecOrigin + m_vecOrigin + [textPadding, 8], m_strTitle, m_vecSize, g_fntDefault); } } - - if (m_strIcon) { - if (m_iFlags & BUTTON_DOWN) - drawpic(m_parent.m_vecOrigin + m_vecOrigin + [2,2], m_strIcon, m_vecIMGSize, m_vecIconColor * 0.25, 1.0f, 0); - else - drawpic(m_parent.m_vecOrigin + m_vecOrigin + [2,2], m_strIcon, m_vecIMGSize, m_vecIconColor, 1.0f, 0); - } - -#else - if (m_iFlags & BUTTON_HOVER) { - drawfill(m_parent.m_vecOrigin + m_vecOrigin, m_vecSize, m_vecColor, 0.25f); - } - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, m_vecSize[1] - 1], [m_vecSize[0], 1], m_vecColor, 1.0f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin, [m_vecSize[0], 1], m_vecColor, 1.0f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, 1], [1, m_vecSize[1] - 2], m_vecColor, 1.0f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [m_vecSize[0] - 1, 1], [1, m_vecSize[1] - 2], m_vecColor, 1.0f); - - - float textPadding = 8; - - { - vector pos = m_parent.m_vecOrigin + m_vecOrigin; - drawsetcliparea(pos[0], pos[1], m_vecSize[0], m_vecSize[1]); - } - - if (m_keyEquivalent >= 0) { - float length; - string keyText = GetKeyEquivalent(); - - length = Font_StringWidth(keyText, FALSE, g_fntDefault); - textPadding += length + 8; - Font_DrawText(m_parent.m_vecOrigin + m_vecOrigin + [8, 8], keyText, g_fntDefault); - } - - if (m_strTitle) { - if (m_iFlags & BUTTON_LASTACTIVE) { - Font_DrawText(m_parent.m_vecOrigin + m_vecOrigin + [textPadding, 8], m_strTitleActive, g_fntDefault); - } else { - Font_DrawText(m_parent.m_vecOrigin + m_vecOrigin + [textPadding, 8], m_strTitle, g_fntDefault); - } - } - if (m_strIcon) { - if (m_iFlags & BUTTON_DOWN) - drawpic(m_parent.m_vecOrigin + m_vecOrigin + [2,2], m_strIcon, m_vecIMGSize, m_vecIconColor * 0.25, 1.0f, 0); - else - drawpic(m_parent.m_vecOrigin + m_vecOrigin + [2,2], m_strIcon, m_vecIMGSize, m_vecIconColor, 1.0f, 0); - } - - drawresetcliparea(); -#endif } bool diff --git a/src/vgui/ui_checkbox.qc b/src/vgui/ui_checkbox.qc index 346bbd17..287acefe 100644 --- a/src/vgui/ui_checkbox.qc +++ b/src/vgui/ui_checkbox.qc @@ -79,7 +79,6 @@ void VGUICheckbox::SetValue (int iValue) void VGUICheckbox::Draw(void) { -#ifndef CLASSIC_VGUI VGUITheme theme = GetTheme(); theme.DrawControlBackground(m_parent.m_vecOrigin + m_vecOrigin, m_vecSize, VGUI_STATE_ACTIVE); @@ -89,31 +88,14 @@ void VGUICheckbox::Draw(void) } if (m_iFlags & CHECKBOX_CHECKED) { - drawpic(m_parent.m_vecOrigin + m_vecOrigin, "textures/ui/steam/icon_checked", [16,16], [1,1,1], 1.0f, 0); + drawpic(m_parent.m_vecOrigin + m_vecOrigin, "gfx/icon16/bullet_toggle_plus", [16,16], [1,1,1], 1.0f, 0); } else { - drawpic(m_parent.m_vecOrigin + m_vecOrigin, "textures/ui/steam/icon_emptybox", [16,16], [1,1,1], 1.0f, 0); + drawpic(m_parent.m_vecOrigin + m_vecOrigin, "gfx/icon16/bullet_black", [16,16], [1,1,1], 1.0f, 0); } if (m_strTitle) { theme.DrawText(m_parent.m_vecOrigin + m_vecOrigin + [24, 3], m_strTitle, m_vecSize, g_fntDefault); } -#else - if (m_iFlags & CHECKBOX_DOWN) { - drawfill(m_parent.m_vecOrigin + m_vecOrigin, [m_vecSize[0], 1], m_vecColor, 1.0f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, m_vecSize[1] - 1], [m_vecSize[0], 1], m_vecColor, 1.0f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, 1], [1, m_vecSize[1] - 2], m_vecColor, 1.0f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [m_vecSize[0] - 1, 1], [1, m_vecSize[1] - 2], m_vecColor, 1.0f); - } - - if (m_iFlags & CHECKBOX_CHECKED) { - drawpic(m_parent.m_vecOrigin + m_vecOrigin, "textures/ui/steam/icon_checked", [16,16], m_vecColor, 1.0f, 0); - } else { - drawpic(m_parent.m_vecOrigin + m_vecOrigin, "textures/ui/steam/icon_emptybox", [16,16], m_vecColor, 1.0f, 0); - } - if (m_strTitle) { - Font_DrawText(m_parent.m_vecOrigin + m_vecOrigin + [24, 3], m_strTitle, g_fntDefault); - } -#endif } bool VGUICheckbox::Input (float flEVType, float flKey, float flChar, float flDevID) diff --git a/src/vgui/ui_commandbutton.qc b/src/vgui/ui_commandbutton.qc new file mode 100644 index 00000000..7656b5d8 --- /dev/null +++ b/src/vgui/ui_commandbutton.qc @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2016-2022 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +enumflags +{ + BUTTON_HOVER, + BUTTON_DOWN, + BUTTON_LASTACTIVE, + BUTTON_CUSTOMFLAGS +}; + +/* TODO: MOVE THESE INTO VGUIButton! COMPILER NEEDS TO BE FIXED FIRST HOWEVER. */ +.void(void) tmpVGUIButton1; + +/** VGUI Widget: Command Menu Button + +@ingroup vgui +*/ +class VGUICommandButton:VGUIButton +{ +public: + void VGUICommandButton(void); + + /* overrides */ + virtual void Draw(void); + virtual bool Input(float,float,float,float); + + nonvirtual bool WillDisplay(void); + nonvirtual void SetMapCondition(string); + nonvirtual void SetTeamCondition(string); + nonvirtual void SetClassCondition(string); + nonvirtual void SetClientCommand(string); +private: + + string m_strMapCondition; + string m_strTeamCondition; + string m_strClassCondition; +}; + +void +VGUICommandButton::VGUICommandButton(void) +{ + m_strMapCondition = __NULL__; + m_strTeamCondition = __NULL__; + m_strClassCondition = __NULL__; +} + +void +VGUICommandButton::SetMapCondition(string condition) +{ + m_strMapCondition = condition; +} + +void +VGUICommandButton::SetTeamCondition(string condition) +{ + m_strTeamCondition = condition; +} + +void +VGUICommandButton::SetClassCondition(string condition) +{ + m_strClassCondition = condition; +} + +void +VGUICommandButton::SetClientCommand(string condition) +{ +} + +bool +VGUICommandButton::WillDisplay(void) +{ + if (STRING_SET(m_strMapCondition)) { + + } + + if (STRING_SET(m_strTeamCondition)) { + + } + + if (STRING_SET(m_strClassCondition)) { + + } + + return (true); +} + +void +VGUICommandButton::Draw(void) +{ + super::Draw(); + //VGUIWidget::Draw(); +} + +bool +VGUICommandButton::Input(float flEVType, float flKey, float flChar, float flDevID) +{ + bool returnValue = super::Input(flEVType, flKey, flChar, flDevID); + + if (!returnValue) { + //return VGUIWidget::Input(flEVType, flKey, flChar, flDevID); + } + + return (returnValue); +} diff --git a/src/vgui/ui_console.qc b/src/vgui/ui_console.qc new file mode 100644 index 00000000..db4ceada --- /dev/null +++ b/src/vgui/ui_console.qc @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2016-2022 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifdef MENU +/** VGUI: Console + +A 'portable' console. It takes up less space. +Not sure what the benefit of it is besides that. + +@ingroup vgui +*/ +class VGUIConsole:VGUIWindow +{ +public: + void VGUIConsole(void); + virtual void Spawned(void); + nonvirtual void ConsoleResized(void); + +private: + VGUIFrame m_outlineFrame; + VGUIButton m_submitButton; + VGUITextBox m_commandBox; +}; + +void +VGUIConsole::VGUIConsole(void) +{ + m_outlineFrame = __NULL__; + m_submitButton = __NULL__; + m_commandBox = __NULL__; +} + +void +VGUIConsole::ConsoleResized(void) +{ + m_outlineFrame.SetSize(GetSize() - [16, 76]); + m_commandBox.SetSize([GetSizeWidth() - 88,24]); + m_commandBox.SetPos([8, GetSizeHeight() - 32]); + m_submitButton.SetPos([GetSizeWidth() - 72, GetSizeHeight() - 32]); +} + +void +VGUIConsole::Spawned(void) +{ + super::Spawned(); + + SetTitle("Console"); + SetSize([560, 400]); + SetPos([40, 40]); + m_outlineFrame = spawn(VGUIFrame); + m_outlineFrame.SetPos([8,36]); + m_outlineFrame.SetSize([544,324]); + + m_commandBox = spawn(VGUITextBox); + m_commandBox.SetPos([8,368]); + m_commandBox.SetSize([472,24]); + + m_submitButton = spawn(VGUIButton); + m_submitButton.SetSize([64,24]); + m_submitButton.SetPos([488,368]); + m_submitButton.SetTitle("Submit"); + + SetStyleMask( VGUIWindowStyleDefault | VGUIWindowResizeable ); + CallOnResize(ConsoleResized); + Add(m_outlineFrame); + Add(m_commandBox); + Add(m_submitButton); +} +#endif diff --git a/src/vgui/ui_frame.qc b/src/vgui/ui_frame.qc index 12df6c1a..50ef8c25 100644 --- a/src/vgui/ui_frame.qc +++ b/src/vgui/ui_frame.qc @@ -40,16 +40,9 @@ VGUIFrame::VGUIFrame(void) void VGUIFrame::Draw(void) { -#ifdef CLASSIC_VGUI - drawfill(m_parent.m_vecOrigin + m_vecOrigin, [m_vecSize[0], 1], m_vecColor, 1.0f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, m_vecSize[1] - 1], [m_vecSize[0], 1], m_vecColor, 1.0f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, 1], [1, m_vecSize[1] - 2], m_vecColor, 1.0f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [m_vecSize[0] - 1, 1], [1, m_vecSize[1] - 2], m_vecColor, 1.0f); -#else drawfill(m_parent.m_vecOrigin + m_vecOrigin, [m_vecSize[0], 1], [1,1,1], 0.5f); drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, m_vecSize[1] - 1], [m_vecSize[0], 1], [0,0,0], 0.5f); drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, 1], [1, m_vecSize[1] - 2], [1,1,1], 0.5f); drawfill(m_parent.m_vecOrigin + m_vecOrigin + [m_vecSize[0] - 1, 1], [1, m_vecSize[1] - 2], [0,0,0], 0.5f); -#endif } diff --git a/src/vgui/ui_label.qc b/src/vgui/ui_label.qc index ccc7a32d..b26a2696 100644 --- a/src/vgui/ui_label.qc +++ b/src/vgui/ui_label.qc @@ -30,6 +30,7 @@ public: virtual bool Input(float, float, float, float); virtual void Spawned(void); virtual void SetTextSize(int); + virtual void SetAlignment(float); private: string m_strTitle; @@ -53,11 +54,7 @@ VGUILabel::Spawned(void) void VGUILabel::SetTitle (string strName) { -#ifndef CLASSIC_VGUI - m_strTitle = strName; -#else - m_strTitle = sprintf("%s%s", Font_RGBtoHex(UI_MAINCOLOR), strName); -#endif + m_strTitle = sprintf("%s%s", Font_RGBtoHex(UI_FGCOLOR), strName); drawfont = g_fntDefault.iID; if (GetSize() == [0,0]) { @@ -73,6 +70,16 @@ VGUILabel::SetTextSize(int val) m_textSize = val; } +void +VGUILabel::SetAlignment(float alignment) +{ + m_labelFlags &= ~AF_LEFT; + m_labelFlags &= ~AF_TOP; + m_labelFlags &= ~AF_RIGHT; + m_labelFlags &= ~AF_BOTTOM; + m_labelFlags |= alignment; +} + void VGUILabel::Draw(void) { @@ -82,14 +89,11 @@ VGUILabel::Draw(void) pos = m_parent.m_vecOrigin + m_vecOrigin; size = m_vecSize; - drawsetcliparea(pos[0], pos[1], size[0], size[1]); if (!m_textSize) Font_DrawField(pos, size, m_strTitle, g_fntDefault, m_labelFlags); else Font_DrawFieldAtHeight(pos, size, m_textSize, m_strTitle, g_fntDefault, m_labelFlags); - - drawresetcliparea(); } } diff --git a/src/vgui/ui_list.qc b/src/vgui/ui_list.qc index 90f7ab53..9b86ea5a 100644 --- a/src/vgui/ui_list.qc +++ b/src/vgui/ui_list.qc @@ -66,23 +66,17 @@ void VGUIList::Spawned(void) void VGUIList::Draw(void) { + VGUITheme theme = GetTheme(); int iMaxDisplay; if (!m_iItemCount) { return; } -#ifdef CLASSIC_VGUI - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, m_vecSize[1] - 1], [m_vecSize[0], 1], UI_MAINCOLOR, 1.0f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin, [m_vecSize[0], 1], UI_MAINCOLOR, 1.0f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, 1], [1, m_vecSize[1] - 2], UI_MAINCOLOR, 1.0f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [m_vecSize[0] - 1, 1], [1, m_vecSize[1] - 2], UI_MAINCOLOR, 1.0f); -#else drawfill(m_parent.m_vecOrigin + m_vecOrigin, m_vecSize, [0,0,0], 0.25f); drawfill(m_parent.m_vecOrigin + m_vecOrigin, [m_vecSize[0], 1], [0,0,0], 0.5f); drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, m_vecSize[1] - 1], [m_vecSize[0], 1], [1,1,1], 0.5f); drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, 1], [1, m_vecSize[1] - 2], [0,0,0], 0.5f); drawfill(m_parent.m_vecOrigin + m_vecOrigin + [m_vecSize[0] - 1, 1], [1, m_vecSize[1] - 2], [1,1,1], 0.5f); -#endif vector vecOffset = [8,8]; @@ -100,7 +94,7 @@ void VGUIList::Draw(void) drawfill(m_parent.m_vecOrigin + m_vecOrigin + vecOffset + [-7,-3], [m_vecSize[0] - 2, 18], [1,1,1], 0.1f); } - Font_DrawText(m_parent.m_vecOrigin + m_vecOrigin + vecOffset, m_strItems[i], g_fntDefault); + theme.DrawText(m_parent.m_vecOrigin + m_vecOrigin + vecOffset, m_strItems[i], m_vecSize, g_fntDefault); vecOffset[1] += 20; } drawresetcliparea(); diff --git a/src/vgui/ui_listbox.qc b/src/vgui/ui_listbox.qc index 21e734cb..f1816886 100644 --- a/src/vgui/ui_listbox.qc +++ b/src/vgui/ui_listbox.qc @@ -94,6 +94,8 @@ void VGUIListBox::AddItem (string strItem) void VGUIListBox::Draw(void) { + VGUITheme theme = GetTheme(); + int iMaxDisplay; if (!m_iItemCount) { return; @@ -117,7 +119,7 @@ void VGUIListBox::Draw(void) drawfill(m_parent.m_vecOrigin + m_vecOrigin + vecOffset + [-7,-3], [m_vecSize[0] - 2, 18], [1,1,1], 0.5f); } - Font_DrawText(m_parent.m_vecOrigin + m_vecOrigin + vecOffset, m_strItems[i], g_fntDefault); + theme.DrawText(m_parent.m_vecOrigin + m_vecOrigin + vecOffset, m_strItems[i], m_vecSize, g_fntDefault); vecOffset[1] += 20; } } diff --git a/src/vgui/ui_loadingpanel.qc b/src/vgui/ui_loadingpanel.qc new file mode 100644 index 00000000..48cb5088 --- /dev/null +++ b/src/vgui/ui_loadingpanel.qc @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2016-2022 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +class +VGUILoadingPanel:VGUIWindow +{ + void VGUILoadingPanel(void); + virtual void Spawned(void); + nonvirtual void UpdateProgress(void); + +private: + + VGUILabel m_lblLoading; + VGUIButton m_btnCancel; + VGUIProgressBar m_progressBar; + float timePassed; +}; + +void +VGUILoadingPanel::VGUILoadingPanel(void) +{ + m_lblLoading = __NULL__; + m_btnCancel = __NULL__; +} + +void +VGUILoadingPanel::UpdateProgress(void) +{ + timePassed += frametime; + + if (timePassed > 1.0f) + timePassed = 0.0f; + + m_progressBar.SetProgress(timePassed); +} + +void +VGUILoadingPanel::Spawned(void) +{ + super::Spawned(); + + SetSize( [380,112] ); + SetTitle( "Loading..." ); + SetStyleMask(VGUIWindowTitled); + + m_progressBar = spawn( VGUIProgressBar ); + m_progressBar.SetSize( [260,24] ); + m_progressBar.SetPos( [20,64] ); + + m_btnCancel = spawn( VGUIButton ); + m_btnCancel.SetTitle( "Cancel" ); + m_btnCancel.SetSize( [72,24] ); + m_btnCancel.SetPos( [288,64] ); + + m_lblLoading = spawn( VGUILabel ); + m_lblLoading.SetTitle( "Starting local game server" ); + m_lblLoading.SetSize( [248,16] ); + m_lblLoading.SetPos( [20,40] ); + //m_lblLoading.SetAlignment(AF_NONE); + + //m_btnCancel.SetFunc( QuitGame_No ); + + Add( m_progressBar ); + Add( m_btnCancel ); + Add( m_lblLoading ); + SetPos( ( g_vidsize / 2 ) - ( GetSize() / 2 ) ); +} diff --git a/src/vgui/ui_menubutton.qc b/src/vgui/ui_menubutton.qc index 5438ed58..83bba255 100644 --- a/src/vgui/ui_menubutton.qc +++ b/src/vgui/ui_menubutton.qc @@ -17,10 +17,7 @@ #ifdef MENU enumflags { - MBUTTON_VISIBLE, - MBUTTON_HOVER, - MBUTTON_DOWN, - MBUTTON_SHOWOFFLINE, + MBUTTON_SHOWOFFLINE = BUTTON_CUSTOMFLAGS, MBUTTON_SHOWSP, MBUTTON_SHOWMP }; @@ -32,38 +29,27 @@ enumflags @ingroup vgui */ class -VGUIMenuButton:VGUIWidget +VGUIMenuButton: VGUIButton { public: void VGUIMenuButton(void); - nonvirtual void SetTitle(string); - nonvirtual void SetIcon(string); - nonvirtual void SetFunc(void(void)); virtual void Draw(void); virtual bool Input(float, float, float, float); virtual void Spawned(void); - -private: - vector m_vecColor; - float m_flAlpha; - string m_strTitle; - string m_strIcon; }; void VGUIMenuButton::VGUIMenuButton(void) { - m_vecColor = UI_MAINCOLOR; - m_flAlpha = 1.0f; } void VGUIMenuButton::Spawned(void) { - SetSize([96,24]); - FlagAdd(MBUTTON_VISIBLE | MBUTTON_SHOWOFFLINE | MBUTTON_SHOWSP | MBUTTON_SHOWMP); + super::Spawned(); + FlagAdd(MBUTTON_SHOWOFFLINE | MBUTTON_SHOWSP | MBUTTON_SHOWMP); } void @@ -80,62 +66,12 @@ VGUIMenuButton::Draw(void) } } -#ifndef CLASSIC_VGUI - drawfill(m_parent.m_vecOrigin + m_vecOrigin, m_vecSize, m_vecColor, m_flAlpha); - - if (m_iFlags & BUTTON_DOWN) { - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, m_vecSize[1] - 1], [m_vecSize[0], 1], [1,1,1], 0.5f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin, [m_vecSize[0], 1], [0,0,0], 0.5f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, 1], [1, m_vecSize[1] - 2], [0,0,0], 0.5f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [m_vecSize[0] - 1, 1], [1, m_vecSize[1] - 2], [1,1,1], 0.5f); - } else { - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, m_vecSize[1] - 1], [m_vecSize[0], 1], [0,0,0], 0.5f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin, [m_vecSize[0], 1], [1,1,1], 0.5f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, 1], [1, m_vecSize[1] - 2], [1,1,1], 0.5f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [m_vecSize[0] - 1, 1], [1, m_vecSize[1] - 2], [0,0,0], 0.5f); - } -#else - if (m_iFlags & BUTTON_DOWN) { - drawfill(m_parent.m_vecOrigin + m_vecOrigin, m_vecSize, m_vecColor, 0.25f); - } - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, m_vecSize[1] - 1], [m_vecSize[0], 1], m_vecColor, 1.0f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin, [m_vecSize[0], 1], m_vecColor, 1.0f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, 1], [1, m_vecSize[1] - 2], m_vecColor, 1.0f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [m_vecSize[0] - 1, 1], [1, m_vecSize[1] - 2], m_vecColor, 1.0f); -#endif - - - if (m_strIcon) { - drawpic(m_parent.m_vecOrigin + m_vecOrigin + [4, 4], m_strIcon, [16,16], [1,1,1], 1.0f); - if (m_strTitle) { - Font_DrawText(m_parent.m_vecOrigin + m_vecOrigin + [26, 8], m_strTitle, g_fntDefault); - } - } else { - if (m_strTitle) { - Font_DrawText(m_parent.m_vecOrigin + m_vecOrigin + [8, 8], m_strTitle, g_fntDefault); - } - } + super::Draw(); } bool VGUIMenuButton::Input (float flEVType, float flKey, float flChar, float flDevID) { - bool ret = false; - bool mouseHover = false; - - if (Util_MouseAbove(g_vecMousePos, m_parent.m_vecOrigin + m_vecOrigin, m_vecSize)) { - mouseHover = true; - } - - if (mouseHover == true && HasFlag(BUTTON_HOVER) == false) { - FlagAdd(MBUTTON_HOVER); - // OnMouseEntered(); - } else if (HasFlag(BUTTON_HOVER) && mouseHover == false) { - FlagRemove(MBUTTON_HOVER); - // OnMouseExited(); - } - - // If we're not ingame if (clientstate() == 2 && !g_background) { if (!(m_iFlags & MBUTTON_SHOWSP)) { @@ -147,42 +83,7 @@ VGUIMenuButton::Input (float flEVType, float flKey, float flChar, float flDevID) } } - if (flEVType == IE_KEYDOWN) { - if (flKey == K_MOUSE1) { - if (mouseHover == true) { - m_iFlags |= MBUTTON_DOWN; - ret = true; - } - } - } else if (flEVType == IE_KEYUP) { - if (flKey == K_MOUSE1) { - if (m_iFlags & MBUTTON_DOWN && mouseHover == true) { - if (tmpVGUIMenuButton1) { - tmpVGUIMenuButton1(); - } - ret = true; - } - m_iFlags -= (m_iFlags & MBUTTON_DOWN); - } - } - return (ret); + return super::Input(flEVType, flKey, flChar, flDevID); } -void -VGUIMenuButton::SetTitle (string strName) -{ - m_strTitle = strName; -} - -void -VGUIMenuButton::SetIcon (string strName) -{ - m_strIcon = strName; -} - -void -VGUIMenuButton::SetFunc (void(void) vFunc) -{ - tmpVGUIMenuButton1 = vFunc; -} #endif diff --git a/src/vgui/ui_progressbar.qc b/src/vgui/ui_progressbar.qc new file mode 100644 index 00000000..a718d908 --- /dev/null +++ b/src/vgui/ui_progressbar.qc @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016-2022 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +/** VGUI Widget: Frame + +@ingroup vgui +*/ +class VGUIProgressBar:VGUIWidget +{ +public: + void VGUIProgressBar(void); + + /* overrides */ + virtual void Draw(void); + + nonvirtual void SetProgress(float); + +private: + float m_flProgress; +}; + +void +VGUIProgressBar::VGUIProgressBar(void) +{ + m_flProgress = 1.0f; +} + +void +VGUIProgressBar::SetProgress(float newProgress) +{ + m_flProgress = newProgress; +} + +void VGUIProgressBar::Draw(void) +{ + VGUITheme theme = GetTheme(); + theme.DrawProgressIndicator(m_parent.m_vecOrigin + m_vecOrigin, m_vecSize, m_flProgress, VGUI_STATE_NORMAL); +} diff --git a/src/vgui/ui_radio.qc b/src/vgui/ui_radio.qc index 474eb14f..39a7d2c0 100644 --- a/src/vgui/ui_radio.qc +++ b/src/vgui/ui_radio.qc @@ -88,7 +88,6 @@ void VGUIRadio::SetFunc (void(void) vFunc) void VGUIRadio::Draw(void) { -#ifndef CLASSIC_VGUI VGUITheme theme = GetTheme(); theme.DrawControlBackground(m_parent.m_vecOrigin + m_vecOrigin, m_vecSize, VGUI_STATE_ACTIVE); @@ -97,31 +96,14 @@ void VGUIRadio::Draw(void) theme.DrawBorder(m_parent.m_vecOrigin + m_vecOrigin, m_vecSize, VGUI_BORDER_INSET, __NULL__); } if (m_iFlags & RADIO_ACTIVE) { - drawpic(m_parent.m_vecOrigin + m_vecOrigin, "textures/ui/steam/icon_radiosel", [16,16], [1,1,1], 1.0f, 0); + drawpic(m_parent.m_vecOrigin + m_vecOrigin, "gfx/icon16/bullet_white", [16,16], [1,1,1], 1.0f, 0); } else { - drawpic(m_parent.m_vecOrigin + m_vecOrigin, "textures/ui/steam/icon_radiounsel", [16,16], [1,1,1], 1.0f, 0); + drawpic(m_parent.m_vecOrigin + m_vecOrigin, "gfx/icon16/bullet_black", [16,16], [1,1,1], 1.0f, 0); } if (m_strTitle) { theme.DrawText(m_parent.m_vecOrigin + m_vecOrigin + [24, 3], m_strTitle, m_vecSize, g_fntDefault); } -#else - if (m_iFlags & RADIO_DOWN) { - drawfill(m_parent.m_vecOrigin + m_vecOrigin, [m_vecSize[0], 1], m_vecColor, 1.0f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, m_vecSize[1] - 1], [m_vecSize[0], 1], m_vecColor, 1.0f, 0); - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, 1], [1, m_vecSize[1] - 2], m_vecColor, 1.0f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [m_vecSize[0] - 1, 1], [1, m_vecSize[1] - 2], m_vecColor, 1.0f, 0); - } - if (m_iFlags & RADIO_ACTIVE) { - drawpic(m_parent.m_vecOrigin + m_vecOrigin, "textures/ui/steam/icon_radiosel", [16,16], m_vecColor, 1.0f, 0); - } else { - drawpic(m_parent.m_vecOrigin + m_vecOrigin, "textures/ui/steam/icon_radiounsel", [16,16], m_vecColor, 1.0f, 0); - } - - if (m_strTitle) { - Font_DrawText(m_parent.m_vecOrigin + m_vecOrigin + [24, 3], m_strTitle, g_fntDefault); - } -#endif } bool VGUIRadio::Input (float flEVType, float flKey, float flChar, float flDevID) diff --git a/src/vgui/ui_scrollbar.qc b/src/vgui/ui_scrollbar.qc index 520a39f3..8219474f 100644 --- a/src/vgui/ui_scrollbar.qc +++ b/src/vgui/ui_scrollbar.qc @@ -14,219 +14,254 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -enumflags -{ - SCROLLBAR_UP_DOWN, - SCROLLBAR_DN_DOWN, - SCROLLBAR_SLIDER_DOWN -}; +const vector VGUIScrollbar_ArrowSize = [19,20]; -.void(void) tmpVGUIScrollbar1; - -/** VGUI Widget: Scrollbar - -@ingroup vgui -*/ class VGUIScrollbar:VGUIWidget { -public: + int m_hold; + int m_hover; + + int m_height; + int m_theight; + int m_scroll; + int m_minus; + int m_maxvisible; + int m_totalentries; + int m_itemheight; + virtual void(void) m_changed = 0; + + int m_up_hover; + int m_up_hold; + int m_dn_hover; + int m_dn_hold; + void VGUIScrollbar(void); - - /** Sets the ??? */ - nonvirtual void SetLength(int); - nonvirtual int GetLength(void); - nonvirtual void SetMin(float); - nonvirtual float GetMin(void); - nonvirtual void SetMax(float); - nonvirtual float GetMax(void); - nonvirtual void SetStep(float); - nonvirtual float GetStep(void); - nonvirtual void SetValue(float,int); - nonvirtual float GetValue(void); - nonvirtual void CallOnChange(void(void)); - virtual void Draw(void); - virtual bool Input(float, float, float, float); + virtual float Input(float, float, float, float); -private: - vector m_vecColor; - float m_flAlpha; - - int m_iLength; - - float m_flMin; - float m_flMax; - float m_flStep; - float m_flValue; + virtual int GetValue(void); + virtual void SetStep(int); + virtual void SetMin(int); + virtual void SetValue(int); + virtual void SetMax(int); + virtual void SetLength(int); + virtual void SetItemheight(int) ; + virtual void CallOnChange(void(void)); + + nonvirtual void DrawArrowUp(vector); + nonvirtual void DrawArrowDown(vector); }; -void VGUIScrollbar::VGUIScrollbar(void) +void +VGUIScrollbar::VGUIScrollbar(void) { - m_vecColor = UI_MAINCOLOR; - m_flAlpha = 1.0f; + /* There's the physical length (t_length) and the actual length + * (border, etc. ignored) */ + SetItemheight(20); + SetLength(128); } -void VGUIScrollbar::Draw(void) +void +VGUIScrollbar::SetStep(int step) { - vector vecSize = [20, m_iLength]; - vector vecUpPos = m_parent.m_vecOrigin + m_vecOrigin; - vector vecDownPos = m_parent.m_vecOrigin + m_vecOrigin + [0, m_iLength - 20]; - vector vecSliderPos = m_parent.m_vecOrigin + m_vecOrigin + [0, 20]; -#ifndef CLASSIC_VGUI +} + +void +VGUIScrollbar::SetMin(int step) +{ + +} + + +void +VGUIScrollbar::DrawArrowUp(vector vecPos) +{ VGUITheme theme = GetTheme(); - - vecSliderPos[1] += (m_iLength - 60) * (m_flValue / m_flMax); - - if (m_iFlags & BUTTON_DOWN) { - theme.DrawScrollbar(m_parent.m_vecOrigin + m_vecOrigin, vecSize, VGUI_STATE_ACTIVE); + if (m_up_hold) { + theme.DrawButton(vecPos, VGUIScrollbar_ArrowSize, VGUI_STATE_ACTIVE); } else { - theme.DrawScrollbar(m_parent.m_vecOrigin + m_vecOrigin, vecSize, VGUI_STATE_NORMAL); + theme.DrawButton(vecPos, VGUIScrollbar_ArrowSize, VGUI_STATE_NORMAL); } - // Slider Button - if (m_iFlags & SCROLLBAR_SLIDER_DOWN) { - theme.DrawScroller(vecSliderPos, [20,20], VGUI_STATE_ACTIVE); - } else { - theme.DrawScroller(vecSliderPos, [20,20], VGUI_STATE_NORMAL); - } - - // Button UP - if (m_iFlags & SCROLLBAR_UP_DOWN) { - theme.DrawButton(vecUpPos, [20,20], VGUI_STATE_ACTIVE); - } else { - theme.DrawButton(vecUpPos, [20,20], VGUI_STATE_NORMAL); - } - drawpic(vecUpPos + [2,2], "textures/ui/steam/icon_up", [16,16], [1,1,1], 1.0f, 0); - - if (m_iFlags & SCROLLBAR_DN_DOWN) { - theme.DrawButton(vecDownPos, [20,20], VGUI_STATE_ACTIVE); - } else { - theme.DrawButton(vecDownPos, [20,20], VGUI_STATE_NORMAL); - } - drawpic(vecDownPos + [2,2], "textures/ui/steam/icon_down", [16,16], [1,1,1], 1.0f, 0); - -#else - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, vecSize[1] - 1], [vecSize[0], 1], m_vecColor, 1.0f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin, [vecSize[0], 1], m_vecColor, 1.0f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, 1], [1, vecSize[1] - 2], m_vecColor, 1.0f); - drawfill(m_parent.m_vecOrigin + m_vecOrigin + [vecSize[0] - 1, 1], [1, vecSize[1] - 2], m_vecColor, 1.0f); - - if (m_iFlags & SCROLLBAR_UP_DOWN) { - drawfill(vecUpPos, [20,20], m_vecColor, 0.25f); - drawfill(vecUpPos, [20, 1], m_vecColor, 1.0f); - drawfill(vecUpPos + [0, 19], [20, 1], m_vecColor, 1.0f); - drawfill(vecUpPos + [0, 1], [1, 18], m_vecColor, 1.0f); - drawfill(vecUpPos + [19, 1], [1, 18], m_vecColor, 1.0f); - } else { - drawfill(vecUpPos, [20, 1], [1,1,1], 0.5f); - drawfill(vecUpPos + [0, 19], [20, 1], m_vecColor, 1.0f); - drawfill(vecUpPos + [0, 1], [1, 18], m_vecColor, 1.0f); - drawfill(vecUpPos + [19, 1], [1, 18], m_vecColor, 1.0f); - } - drawpic(vecUpPos + [2,2], "textures/ui/steam/icon_up", [16,16], m_vecColor, 1.0f, 0); - - // Button DOWN - if (m_iFlags & SCROLLBAR_DN_DOWN) { - drawfill(vecDownPos, [20,20], m_vecColor, 0.25f); - drawfill(vecDownPos, [20, 1], m_vecColor, 1.0f); - drawfill(vecDownPos + [0, 19], [20, 1], m_vecColor, 1.0f); - drawfill(vecDownPos + [0, 1], [1, 18], m_vecColor, 1.0f); - drawfill(vecDownPos + [19, 1], [1, 18], m_vecColor, 1.0f); - } else { - drawfill(vecDownPos, [20, 1], m_vecColor, 1.0f); - drawfill(vecDownPos+ [0, 19], [20, 1], m_vecColor, 1.0f); - drawfill(vecDownPos + [0, 1], [1, 18], m_vecColor, 1.0f); - drawfill(vecDownPos + [19, 1], [1, 18], m_vecColor, 1.0f); - } - drawpic(vecDownPos + [2,2], "textures/ui/steam/icon_down", [16,16], m_vecColor, 1.0f, 0); -#endif + drawpic(vecPos + [2,2], "gfx/icon16/bullet_arrow_up", [16,16], [1,1,1], 1.0f, 0); } -bool VGUIScrollbar::Input (float flEVType, float flKey, float flChar, float flDevID) +void +VGUIScrollbar::DrawArrowDown(vector vecPos) { - bool ret = false; - vector vecUpPos = m_parent.m_vecOrigin + m_vecOrigin; - vector vecDownPos = m_parent.m_vecOrigin + m_vecOrigin + [0, m_iLength - 20]; - - if (flEVType == IE_KEYDOWN) { - if (flKey == K_MOUSE1) { - if (Util_MouseAbove(g_vecMousePos, vecUpPos, [20,20])) { - m_iFlags |= SCROLLBAR_UP_DOWN; - ret = true; - } else if (Util_MouseAbove(g_vecMousePos, vecDownPos, [20,20])) { - m_iFlags |= SCROLLBAR_DN_DOWN; - ret = true; - } - } - } else if (flEVType == IE_KEYUP) { - if (flKey == K_MOUSE1) { - if (m_iFlags & SCROLLBAR_UP_DOWN && Util_MouseAbove(g_vecMousePos, vecUpPos, [20,20])) { - SetValue(GetValue() - GetStep(), TRUE); - } else if (m_iFlags & SCROLLBAR_DN_DOWN && Util_MouseAbove(g_vecMousePos, vecDownPos, [20,20])) { - SetValue(GetValue() + GetStep(), TRUE); - } - m_iFlags -= (m_iFlags & SCROLLBAR_UP_DOWN); - m_iFlags -= (m_iFlags & SCROLLBAR_DN_DOWN); - } else if (flKey == K_MWHEELDOWN && Util_MouseAbove(g_vecMousePos, m_parent.m_vecOrigin + m_vecOrigin, [20, m_iLength])) { - SetValue(GetValue() + GetStep(), TRUE); - } else if (flKey == K_MWHEELUP && Util_MouseAbove(g_vecMousePos, m_parent.m_vecOrigin + m_vecOrigin, [20, m_iLength])) { - SetValue(GetValue() - GetStep(), TRUE); + VGUITheme theme = GetTheme(); + if (m_dn_hold) { + theme.DrawButton(vecPos, VGUIScrollbar_ArrowSize, VGUI_STATE_ACTIVE); + } else { + theme.DrawButton(vecPos, VGUIScrollbar_ArrowSize, VGUI_STATE_NORMAL); + } + + drawpic(vecPos + [2,2], "gfx/icon16/bullet_arrow_down", [16,16], [1,1,1], 1.0f, 0); +} + +void +VGUIScrollbar::Draw(void) +{ + VGUITheme theme = GetTheme(); + int barheight = 0; + float barstep = 0; + + barheight = (float)(m_minus) / (float)(m_totalentries) * m_theight; + + drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0,VGUIScrollbar_ArrowSize[1]], [VGUIScrollbar_ArrowSize[0],m_theight], [1.0f,1.0f,1.0f], 0.1f); + + DrawArrowUp([m_parent.m_vecOrigin[0]+m_vecOrigin[0],m_parent.m_vecOrigin[1]+m_vecOrigin[1]]); + DrawArrowDown([m_parent.m_vecOrigin[0]+m_vecOrigin[0],m_parent.m_vecOrigin[1]+m_vecOrigin[1]+m_theight + VGUIScrollbar_ArrowSize[1]]); + + + if (barheight < 20) + barheight = 20; + + barstep = m_theight - barheight; + barstep *= (float)(m_scroll) / (float)(m_maxvisible); + + /* too few entries? don't even bother */ + if (m_totalentries * m_itemheight < m_height) { + drawfill([m_parent.m_vecOrigin[0]+m_vecOrigin[0],m_parent.m_vecOrigin[1]+m_vecOrigin[1]+VGUIScrollbar_ArrowSize[1]], [VGUIScrollbar_ArrowSize[0],m_theight], [0.25,0.25,0.25], 1.0f); + return; + } + + drawfill([m_parent.m_vecOrigin[0]+m_vecOrigin[0],m_parent.m_vecOrigin[1]+m_vecOrigin[1]+VGUIScrollbar_ArrowSize[1]+barstep], [VGUIScrollbar_ArrowSize[0],barheight], UI_MAINCOLOR, UI_MAINALPHA); + + if (!m_hold) { + theme.DrawButton([m_parent.m_vecOrigin[0]+m_vecOrigin[0],m_parent.m_vecOrigin[1]+m_vecOrigin[1]+VGUIScrollbar_ArrowSize[1]+barstep], [VGUIScrollbar_ArrowSize[0],barheight], VGUI_STATE_NORMAL); + } else { + theme.DrawButton([m_parent.m_vecOrigin[0]+m_vecOrigin[0],m_parent.m_vecOrigin[1]+m_vecOrigin[1]+VGUIScrollbar_ArrowSize[1]+barstep], [VGUIScrollbar_ArrowSize[0],barheight], VGUI_STATE_ACTIVE); + } +} + +float +VGUIScrollbar::Input(float type, float x, float y, float devid) +{ + int barheight = 0; + float barstep = 0; + float returnVal = false; + + /* too few entries? don't even bother */ + if (m_totalentries * m_itemheight < m_height) { + return false; + } + + barheight = (float)(m_minus) / (float)(m_totalentries) * m_theight; + + if (barheight < 20) + barheight = 20; + + barstep = m_theight - barheight; + barstep *= (float)(m_scroll) / (float)(m_maxvisible); + + if (Util_MouseAbove(g_vecMousePos, m_parent.m_vecOrigin + m_vecOrigin, VGUIScrollbar_ArrowSize)) { + m_up_hover = TRUE; + } else { + m_up_hover = FALSE; + } + + if (Util_MouseAbove(g_vecMousePos, m_parent.m_vecOrigin + m_vecOrigin + [0, m_theight + VGUIScrollbar_ArrowSize[1]], VGUIScrollbar_ArrowSize)) { + m_dn_hover = TRUE; + } else { + m_dn_hover = FALSE; + } + + if (Util_MouseAbove(g_vecMousePos, m_parent.m_vecOrigin + m_vecOrigin + [0, barstep + VGUIScrollbar_ArrowSize[1]], [VGUIScrollbar_ArrowSize[0],barheight])) { + m_hover = TRUE; + } else { + m_hover = FALSE; + } + + if (m_up_hover && type == IE_KEYDOWN && x == K_MOUSE1) { + m_up_hold = TRUE; + returnVal = true; + } else if (type == IE_KEYUP && x == K_MOUSE1) { + m_up_hold = FALSE; + } + if (m_up_hold) { + SetValue(m_scroll - 1); + } + + if (m_dn_hover && type == IE_KEYDOWN && x == K_MOUSE1) { + m_dn_hold = TRUE; + returnVal = true; + } else if (type == IE_KEYUP && x == K_MOUSE1) { + m_dn_hold = FALSE; + } + if (m_dn_hold) { + SetValue(m_scroll + 1); + } + + if (m_hover && type == IE_KEYDOWN && x == K_MOUSE1) { + m_hold = TRUE; + returnVal = true; + } else if (type == IE_KEYUP && x == K_MOUSE1) { + m_hold = FALSE; + } + + if (m_hold) { + if (g_vecMousePos[0] != g_lastmousepos[0] || g_vecMousePos[1] != g_lastmousepos[1]) { + int mdelta; + float m_value; + /* The - 10 is putting the slider in the middle of the cursor */ + mdelta = (g_vecMousePos[1] - (barheight / 2)) - ( m_parent.m_vecOrigin[1] + m_vecOrigin[1]); + m_value = ((float)mdelta / (float)m_theight); + m_value = bound(0.0f, m_value, 1.0f); + + SetValue(rint(m_totalentries * m_value)); + g_lastmousepos[0] = g_vecMousePos[0]; + g_lastmousepos[1] = g_vecMousePos[1]; + + /*if (m_changed) { + m_changed(m_value); + }*/ } } - return (ret); + + return (returnVal); } -void VGUIScrollbar::SetLength (int iLength) +int +VGUIScrollbar::GetValue(void) { - m_iLength = iLength; -} -int VGUIScrollbar::GetLength(void) -{ - return m_iLength; + return m_scroll; } -void VGUIScrollbar::SetMin (float flVal) +void +VGUIScrollbar::SetValue(int val) { - m_flMin = flVal; -} -float VGUIScrollbar::GetMin(void) -{ - return m_flMin; -} + m_scroll = bound(0,val,m_totalentries); -void VGUIScrollbar::SetMax (float flVal) -{ - m_flMax = flVal; -} -float VGUIScrollbar::GetMax(void) -{ - return m_flMax; -} - -void VGUIScrollbar::SetStep (float flVal) -{ - m_flStep = flVal; -} -float VGUIScrollbar::GetStep(void) -{ - return m_flStep; -} - -void VGUIScrollbar::SetValue (float flVal, int iCallBack) -{ - m_flValue = bound(m_flMin, flVal, m_flMax); - - if (tmpVGUIScrollbar1 && iCallBack) { - tmpVGUIScrollbar1(); + if (m_changed) { + m_changed(); } } -float VGUIScrollbar::GetValue(void) + +void +VGUIScrollbar::SetMax(int val) { - return m_flValue; + m_minus = m_height / m_itemheight; + m_totalentries = val; + m_maxvisible = m_totalentries - m_minus; } -void VGUIScrollbar::CallOnChange (void(void) vFunc) +void +VGUIScrollbar::SetLength(int val) { - tmpVGUIScrollbar1 = vFunc; + m_height = val; + m_theight = m_height - (VGUIScrollbar_ArrowSize[1] * 2); +} + +void +VGUIScrollbar::SetItemheight(int val) +{ + m_itemheight = val; +} + +void +VGUIScrollbar::CallOnChange(void(void) vFunc) +{ + m_changed = vFunc; } diff --git a/src/vgui/ui_textbox.qc b/src/vgui/ui_textbox.qc index 8900e61d..61ada18f 100644 --- a/src/vgui/ui_textbox.qc +++ b/src/vgui/ui_textbox.qc @@ -69,18 +69,14 @@ string VGUITextBox::GetText(void) void VGUITextBox::Draw(void) { - -#ifdef CLASSIC_VGUI VGUITheme theme = GetTheme(); - theme. DrawTextBackground(m_parent.m_vecOrigin + m_vecOrigin, m_vecSize, VGUI_STATE_NORMAL); -#else drawfill(m_parent.m_vecOrigin + m_vecOrigin, m_vecSize, [0,0,0], 0.25f); drawfill(m_parent.m_vecOrigin + m_vecOrigin, [m_vecSize[0], 1], [0,0,0], 0.5f); drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, m_vecSize[1] - 1], [m_vecSize[0], 1], [1,1,1], 0.5f); drawfill(m_parent.m_vecOrigin + m_vecOrigin + [0, 1], [1, m_vecSize[1] - 2], [0,0,0], 0.5f); drawfill(m_parent.m_vecOrigin + m_vecOrigin + [m_vecSize[0] - 1, 1], [1, m_vecSize[1] - 2], [1,1,1], 0.5f); -#endif + m_flTime += frametime * 2; /* these are to deal with text going off-screen */ @@ -90,17 +86,13 @@ void VGUITextBox::Draw(void) // blinking cursor if (m_iFlags & TEXTBOX_FOCUS) { if (rint(m_flTime) & 1) { - drawsetcliparea(m_parent.m_vecOrigin[0] + m_vecOrigin[0], m_parent.m_vecOrigin[1] + m_vecOrigin[1], m_vecSize[0], m_vecSize[1]); - Font_DrawText(m_parent.m_vecOrigin + m_vecOrigin + [8 - ofs, 8], sprintf("%s|", m_strText), g_fntDefault); - drawresetcliparea(); + theme.DrawText(m_parent.m_vecOrigin + m_vecOrigin + [8 - ofs, 8], sprintf("%s|", m_strText), m_vecSize, g_fntDefault); return; } } if (m_strText) { - drawsetcliparea(m_parent.m_vecOrigin[0] + m_vecOrigin[0], m_parent.m_vecOrigin[1] + m_vecOrigin[1], m_vecSize[0], m_vecSize[1]); - Font_DrawText(m_parent.m_vecOrigin + m_vecOrigin + [8 - ofs, 8], m_strText, g_fntDefault); - drawresetcliparea(); + theme.DrawText(m_parent.m_vecOrigin + m_vecOrigin + [8 - ofs, 8], m_strText, m_vecSize, g_fntDefault); } } diff --git a/src/vgui/ui_theme.qc b/src/vgui/ui_theme.qc index 2ace713f..f45f973e 100644 --- a/src/vgui/ui_theme.qc +++ b/src/vgui/ui_theme.qc @@ -10,17 +10,19 @@ also referred to as TrackerUI has changed many times in appearance and we'd like means of handling any such styles. */ -#ifdef CLASSIC_VGUI - #ifndef UI_MAINCOLOR - #define UI_MAINCOLOR [255,170,0] / 255 - #endif - #ifndef UI_MAINALPHA - #define UI_MAINALPHA 255 - #endif -#else - var vector UI_MAINCOLOR; - var float UI_MAINALPHA; -#endif + +var vector UI_MAINCOLOR; +var vector UI_FGCOLOR; +var float UI_MAINALPHA; +var vector UI_HICOLOR; +var vector UI_FILLCOLOR; +var vector UI_LOCOLOR; +var vector UI_BORDERCOLOR; +var float UI_BORDERALPHA; +var bool UI_ROUNDED; +var bool UI_NOICONS; +var vector UI_HOVERCOLOR; +var float UI_HOVERALPHA; /** State of the widget we're going to draw. */ typedef enum @@ -61,6 +63,8 @@ public: virtual void DrawTextBackground(vector, vector, VGUIDrawState_t); /** Draw a window background at the specified position, size and VGUIDrawState_t. */ virtual void DrawWindowBackground(vector, vector, VGUIDrawState_t); + /** Draw a window background at the specified position, size and VGUIDrawState_t. */ + virtual void DrawWindowTitle(vector, vector, string, string, font_s, VGUIDrawState_t); /** Draw a button body at the specified position, size and VGUIDrawState_t. */ virtual void DrawButton(vector, vector, VGUIDrawState_t); /** Draw a scroller at the specified position, size and VGUIDrawState_t. */ @@ -80,26 +84,33 @@ private: VGUIColor m_textBackgroundColor; VGUIColor m_textColor; VGUIColor m_windowBorderColor; + VGUIColor m_hilightColor; + VGUIColor m_shadowColor; }; void VGUITheme::VGUITheme(void) { m_controlBackgroundColor = spawn(VGUIColor); - //m_controlBackgroundColor.SetColor([0.298, 0.345, 0.267]); - m_controlBackgroundColor.SetColor(UI_MAINCOLOR); + m_controlBackgroundColor. SetColorWithAlpha(UI_MAINCOLOR, 0.0f); + m_windowBackgroundColor = spawn(VGUIColor); - //m_windowBackgroundColor.SetColor([0.298, 0.345, 0.267]); - m_windowBackgroundColor.SetColor(UI_MAINCOLOR); + m_windowBackgroundColor.SetColorWithAlpha(UI_MAINCOLOR, UI_MAINALPHA); + m_textBackgroundColor = spawn(VGUIColor); - //m_textBackgroundColor.SetColor([0.243, 0.275, 0.216]); m_textBackgroundColor.SetColor(UI_MAINCOLOR); + m_textColor = spawn(VGUIColor); - //m_textColor.SetColor([0.847, 0.871, 0.827]); - m_textColor.SetColor(UI_MAINCOLOR); + m_textColor.SetColor(UI_FGCOLOR); + m_windowBorderColor = spawn(VGUIColor); - //m_windowBorderColor.SetColor([0.533, 0.569, 0.502]); - m_windowBorderColor.SetColor(UI_MAINCOLOR); + m_windowBorderColor.SetColor(UI_BORDERCOLOR); + + m_hilightColor = spawn(VGUIColor); + m_hilightColor.SetColorWithAlpha(UI_HICOLOR, 0.5f); + + m_shadowColor = spawn(VGUIColor); + m_shadowColor.SetColorWithAlpha(UI_LOCOLOR, 0.5f); } void @@ -107,16 +118,16 @@ VGUITheme::DrawBorder(vector atPos, vector withSize, VGUIBorderStyle_t borderSty { switch (borderStyle) { case VGUI_BORDER_INSET: - drawfill(atPos + [0, withSize[1] - 1], [withSize[0], 1], [1,1,1], 0.5f); - drawfill(atPos, [withSize[0], 1], [0,0,0], 0.5f); - drawfill(atPos + [0, 1], [1, withSize[1] - 2], [0,0,0], 0.5f); - drawfill(atPos + [withSize[0] - 1, 1], [1, withSize[1] - 2], [1,1,1], 0.5f); + drawfill(atPos + [0, withSize[1] - 1], [withSize[0], 1], m_hilightColor.GetColor(), m_hilightColor.GetAlpha()); + drawfill(atPos, [withSize[0], 1], m_shadowColor.GetColor(), m_shadowColor.GetAlpha()); + drawfill(atPos + [0, 1], [1, withSize[1] - 2], m_shadowColor.GetColor(), m_shadowColor.GetAlpha()); + drawfill(atPos + [withSize[0] - 1, 1], [1, withSize[1] - 2], m_hilightColor.GetColor(), m_hilightColor.GetAlpha()); break; case VGUI_BORDER_OUTSET: - drawfill(atPos + [0, withSize[1] - 1], [withSize[0], 1], [0,0,0], 0.5f); - drawfill(atPos, [withSize[0], 1], [1,1,1], 0.5f); - drawfill(atPos + [0, 1], [1, withSize[1] - 2], [1,1,1], 0.5f); - drawfill(atPos + [withSize[0] - 1, 1], [1, withSize[1] - 2], [0,0,0], 0.5f); + drawfill(atPos + [0, withSize[1] - 1], [withSize[0], 1], m_shadowColor.GetColor(), 0.5f); + drawfill(atPos, [withSize[0], 1], m_hilightColor.GetColor(), 0.5f); + drawfill(atPos + [0, 1], [1, withSize[1] - 2], m_hilightColor.GetColor(), 0.5f); + drawfill(atPos + [withSize[0] - 1, 1], [1, withSize[1] - 2], m_shadowColor.GetColor(), 0.5f); break; case VGUI_BORDER_LINE: drawfill(atPos + [0, withSize[1] - 1], [withSize[0], 1], color.GetColor(), color.GetAlpha()); @@ -154,15 +165,19 @@ VGUITheme::DrawButton(vector atPos, vector withSize, VGUIDrawState_t drawStyle) DrawControlBackground(atPos, withSize, drawStyle); if (drawStyle == VGUI_STATE_ACTIVE) { - drawfill(atPos + [0, withSize[1] - 1], [withSize[0], 1], [1,1,1], 0.5f); - drawfill(atPos, [withSize[0], 1], [0,0,0], 0.5f); - drawfill(atPos + [0, 1], [1, withSize[1] - 2], [0,0,0], 0.5f); - drawfill(atPos + [withSize[0] - 1, 1], [1, withSize[1] - 2], [1,1,1], 0.5f); + drawfill(atPos + [0, withSize[1] - 1], [withSize[0], 1], m_hilightColor.GetColor(), m_hilightColor.GetAlpha()); + drawfill(atPos, [withSize[0], 1], m_shadowColor.GetColor(), m_shadowColor.GetAlpha()); + drawfill(atPos + [0, 1], [1, withSize[1] - 2], m_shadowColor.GetColor(), m_shadowColor.GetAlpha()); + drawfill(atPos + [withSize[0] - 1, 1], [1, withSize[1] - 2], m_hilightColor.GetColor(), m_hilightColor.GetAlpha()); } else { - drawfill(atPos + [0, withSize[1] - 1], [withSize[0], 1], [0,0,0], 0.5f); - drawfill(atPos, [withSize[0], 1], [1,1,1], 0.5f); - drawfill(atPos + [0, 1], [1, withSize[1] - 2], [1,1,1], 0.5f); - drawfill(atPos + [withSize[0] - 1, 1], [1, withSize[1] - 2], [0,0,0], 0.5f); + drawfill(atPos + [0, withSize[1] - 1], [withSize[0], 1], m_shadowColor.GetColor(), m_shadowColor.GetAlpha()); + drawfill(atPos, [withSize[0], 1], m_hilightColor.GetColor(), m_hilightColor.GetAlpha()); + drawfill(atPos + [0, 1], [1, withSize[1] - 2], m_hilightColor.GetColor(), m_hilightColor.GetAlpha()); + drawfill(atPos + [withSize[0] - 1, 1], [1, withSize[1] - 2], m_shadowColor.GetColor(), m_shadowColor.GetAlpha()); + } + + if (drawStyle == VGUI_STATE_HOVER) { + drawfill(atPos, withSize, UI_HOVERCOLOR, UI_HOVERALPHA); } } @@ -170,10 +185,10 @@ void VGUITheme::DrawScroller(vector atPos, vector withSize, VGUIDrawState_t drawStyle) { DrawControlBackground(atPos, withSize, drawStyle); - drawfill(atPos + [0, withSize[1] - 1], [withSize[0], 1], [0,0,0], 0.5f); - drawfill(atPos, [withSize[0], 1], [1,1,1], 0.5f); - drawfill(atPos + [0, 1], [1, withSize[1] - 2], [1,1,1], 0.5f); - drawfill(atPos + [withSize[0] - 1, 1], [1, withSize[1] - 2], [0,0,0], 0.5f); + drawfill(atPos + [0, withSize[1] - 1], [withSize[0], 1], m_shadowColor.GetColor(), m_shadowColor.GetAlpha()); + drawfill(atPos, [withSize[0], 1], m_hilightColor.GetColor(), m_hilightColor.GetAlpha()); + drawfill(atPos + [0, 1], [1, withSize[1] - 2], m_hilightColor.GetColor(), m_hilightColor.GetAlpha()); + drawfill(atPos + [withSize[0] - 1, 1], [1, withSize[1] - 2], m_shadowColor.GetColor(), m_shadowColor.GetAlpha()); } void @@ -185,9 +200,19 @@ VGUITheme::DrawScrollbar(vector atPos, vector withSize, VGUIDrawState_t drawStyl void VGUITheme::DrawProgressIndicator(vector atPos, vector withSize, float progressValue, VGUIDrawState_t drawStyle) { - float barLength = (withSize[0] - 4) * progressValue; - DrawTextBackground(atPos, withSize, drawStyle); - drawfill(atPos + [2, 2], [barLength, withSize[1] - 4], [1,1,1], 1.0f); + drawfill(atPos, [withSize[0], 1], m_shadowColor.GetColor(), m_shadowColor.GetAlpha()); + drawfill(atPos + [0, withSize[1] - 1], [withSize[0], 1], m_hilightColor.GetColor(), m_hilightColor.GetAlpha()); + drawfill(atPos + [0, 1], [1, withSize[1] - 2], m_shadowColor.GetColor(), m_shadowColor.GetAlpha()); + drawfill(atPos + [withSize[0] - 1, 1], [1, withSize[1] - 2], m_hilightColor.GetColor(), m_hilightColor.GetAlpha()); + drawfill(atPos + [1,1], [withSize[0] - 2, withSize[1]-2], m_shadowColor.GetColor(), m_shadowColor.GetAlpha()); + + vector drawPos = [4,4]; + float max = floor(((withSize[0] - 8) * progressValue) / 12); + + for (float i = 0; i < max; i++ ) { + drawfill(atPos + drawPos, [8, 16], UI_FILLCOLOR, 1.0f); + drawPos[0] += 12; + } } void @@ -195,13 +220,74 @@ VGUITheme::DrawText(vector atPos, string withText, vector boundSize, font_s text { //drawsetcliparea(atPos[0], atPos[1], boundSize[0], boundSize[1]); //drawfill(atPos, boundSize, [1,1,1], 0.5f); - Font_DrawText(atPos, withText, textFont); + Font_DrawText_RGB(atPos, withText, UI_FGCOLOR, textFont); //drawresetcliparea(); } void VGUITheme::DrawWindow(vector atPos, vector withSize, VGUIDrawState_t drawStyle) { - DrawWindowBackground(atPos, withSize, drawStyle); - DrawBorder(atPos, withSize, VGUI_BORDER_OUTSET, m_windowBorderColor); -} \ No newline at end of file + static void + DRB(vector pos, vector size, vector rgb, float a) + { + drawpic(pos, "textures/ui/m_topleft.tga", [16,16], rgb, a, 0); + drawpic(pos + [size[0] - 16, 0], "textures/ui/m_topright.tga", [16,16], rgb, a, 0); + drawpic(pos + [0, size[1] - 16], "textures/ui/m_bottomleft.tga", [16,16], rgb, a, 0); + drawpic(pos + [size[0] - 16, size[1] - 16], "textures/ui/m_bottomright.tga", [16,16], rgb, a, 0); + + if (size_x > 32) { + drawpic(pos + [16, 0], "textures/ui/m_top.tga", [size[0] - 32, 16], rgb, a, 0); + drawpic(pos + [16, size[1] - 16], "textures/ui/m_bottom.tga", [size[0] - 32, 16], rgb, a, 0); + } + + if (size_y > 32) { + drawpic(pos + [0, 16], "textures/ui/m_left.tga", [16, size[1] - 32], rgb, a, 0); + drawpic(pos + [size[0] - 16, 16], "textures/ui/m_right.tga", [16, size[1] - 32], rgb, a, 0); + drawpic(pos + [16, 16], "textures/ui/m_mid.tga", [size[0] - 32, size[1] - 32], rgb, a, 0); + } + } + + static void + DRB2(vector pos, vector size, vector rgb, float a) + { + drawpic(pos, "textures/ui/m_linetopleft.tga", [16,16], rgb, a, 0); + drawpic(pos + [size[0] - 16, 0], "textures/ui/m_linetopright.tga", [16,16], rgb, a, 0); + drawpic(pos + [0, size[1] - 16], "textures/ui/m_linebottomleft.tga", [16,16], rgb, a, 0); + drawpic(pos + [size[0] - 16, size[1] - 16], "textures/ui/m_linebottomright.tga", [16,16], rgb, a, 0); + + if (size_x > 32) { + drawpic(pos + [16, 0], "textures/ui/m_linetop.tga", [size[0] - 32, 16], rgb, a, 0); + drawpic(pos + [16, size[1] - 16], "textures/ui/m_linebottom.tga", [size[0] - 32, 16], rgb, a, 0); + } + + if (size_y > 32) { + drawpic(pos + [0, 16], "textures/ui/m_lineleft.tga", [16, size[1] - 32], rgb, a, 0); + drawpic(pos + [size[0] - 16, 16], "textures/ui/m_lineright.tga", [16, size[1] - 32], rgb, a, 0); + drawpic(pos + [16, 16], "textures/ui/m_linemid.tga", [size[0] - 32, size[1] - 32], rgb, a, 0); + } + } + + if (UI_ROUNDED == true) { + DRB(atPos, withSize, m_windowBackgroundColor.GetColor(), m_windowBackgroundColor.GetAlpha()); + + if (UI_BORDERALPHA > 0.0f) { + DRB2(atPos, withSize, m_windowBorderColor.GetColor(), m_windowBorderColor.GetAlpha()); + } + } else { + DrawWindowBackground(atPos, withSize, drawStyle); + DrawBorder(atPos, withSize, VGUI_BORDER_OUTSET, m_windowBorderColor); + } +} + +void +VGUITheme::DrawWindowTitle(vector atPos, vector withSize, string titleText, string withIcon, font_s textFont, VGUIDrawState_t drawStyle) +{ + if (STRING_SET(titleText)) { + if (STRING_SET(withIcon) && UI_NOICONS == false) { + DrawText(atPos + [26, 8], titleText, withSize, textFont); + drawpic(atPos + [4, 4], withIcon, [16,16], [1,1,1], 1.0f, 0); + } else { + DrawText(atPos + [8, 8], titleText, withSize, textFont); + } + } +} diff --git a/src/vgui/ui_window.qc b/src/vgui/ui_window.qc index 28d6449c..c5637610 100644 --- a/src/vgui/ui_window.qc +++ b/src/vgui/ui_window.qc @@ -185,13 +185,8 @@ VGUIWindow::Spawned(void) m_btnClose = spawn(VGUIButton); m_btnClose.SetTitle(__NULL__); - m_btnClose.SetIcon("textures/ui/steam/icon_close"); -#ifdef CLASSIC_VGUI - m_btnClose.SetIconColor(m_vecColor); -#else m_btnClose.SetIconColor([1,1,1]); -#endif m_btnClose.SetColor(m_vecColor); m_btnClose.SetFunc(VGUIWindowButtonClose); m_btnClose.SetSize([20,20]); @@ -243,33 +238,6 @@ VGUIWindow::WindowDidClose(void) void VGUIWindow::Draw(void) { -#ifdef CLASSIC_VGUI - if (m_styleMask & VGUIWindowFullscreen) - drawfill([0,0], g_vidsize, [0,0,0], 0.5); - else - drawfill(m_vecOrigin, m_vecSize, [0,0,0], 0.5); - - if (!(m_styleMask & VGUIWindowBorderless)) { - drawfill(m_vecOrigin, [m_vecSize[0], 1], m_vecColor, 1.0f); - drawfill(m_vecOrigin + [0, m_vecSize[1] - 1], [m_vecSize[0], 1], m_vecColor, 1.0f); - drawfill(m_vecOrigin + [0, 1], [1, m_vecSize[1] - 2], m_vecColor, 1.0f); - drawfill(m_vecOrigin + [m_vecSize[0] - 1, 1], [1, m_vecSize[1] - 2], m_vecColor, 1.0f); - } - - if (m_styleMask & VGUIWindowResizeable) { - drawpic(m_vecOrigin + m_vecSize - [16,16], "textures/ui/steam/icon_resizer", [16,16], m_vecColor, 1.0f, 0); - } - - if (m_styleMask & VGUIWindowTitled) - if (m_strTitle) { - if (m_strIcon) { - Font_DrawText(m_vecOrigin + [26, 8], m_strTitle, g_fntDefault); - drawpic(m_vecOrigin + [4, 4], m_strIcon, [16,16], [1,1,1], 1.0f, 0); - } else { - Font_DrawText(m_vecOrigin + [8, 8], m_strTitle, g_fntDefault); - } - } -#else VGUITheme theme = GetTheme(); if (m_styleMask & VGUIWindowFullscreen) @@ -280,22 +248,19 @@ void VGUIWindow::Draw(void) theme.DrawWindowBackground(m_vecOrigin, m_vecSize, VGUI_STATE_ACTIVE); if (m_styleMask & VGUIWindowResizeable) { - drawpic(m_vecOrigin + m_vecSize - [16,16], "textures/ui/steam/icon_resizer", [16,16], m_vecColor, 1.0f, 0); + drawpic(m_vecOrigin + m_vecSize - [16,16], "gfx/icon16/arrow_out", [16,16], m_vecColor, 1.0f, 0); } - if (m_styleMask & VGUIWindowTitled) - if (m_strTitle) { - if (m_strIcon) { - theme.DrawText(m_vecOrigin + [26, 8], m_strTitle, m_vecSize, g_fntDefault); - drawpic(m_vecOrigin + [4, 4], m_strIcon, [16,16], [1,1,1], 1.0f, 0); - } else { - theme.DrawText(m_vecOrigin + [8, 8], m_strTitle, m_vecSize, g_fntDefault); - } + if (m_styleMask & VGUIWindowTitled) { + theme.DrawWindowTitle(m_vecOrigin, m_vecSize, m_strTitle, m_strIcon, g_fntDefault, VGUI_STATE_ACTIVE); } -#endif super::Draw(); + if (m_styleMask & VGUIWindowClosable) { + drawpic(m_vecOrigin + m_btnClose.m_vecOrigin + [2,2], "gfx/icon16/cross_mono", [16,16], [1,1,1], 1.0f, 0); + } + #ifdef UI_DEVELOPER if (m_iFlags & WINDOW_DRAGGING) { Font_DrawText([8, g_vidsize[1] - 18], sprintf("Window Position: %d, %d\n", m_vecOrigin[0], m_vecOrigin[1]), g_fntDefault); @@ -352,9 +317,20 @@ bool VGUIWindow::Input (float flEVType, float flKey, float flChar, float flDevID ret = true; } + /* if we hadn't had a successful input yet, pass it onto the children */ if (ret == false) { ret = super::Input(flEVType, flKey, flChar, flDevID); } + /* don't send clicks to elements behind our window */ + if (flEVType == IE_KEYDOWN && flKey == K_MOUSE1 && ret == false && Util_MouseAbove(g_vecMousePos, m_vecOrigin, m_vecSize)) { + ret = true; + } + + /* if an input was a success? refocus */ + if (ret == true) { + Focus(); + } + return (ret); }
  2. ={4^ZidAM3m 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 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/date_delete.png b/base/resources.pk3dir/gfx/icon16/date_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..969a6b7239275cbafd223931e3fdc9b1eb482e22 GIT binary patch literal 716 zcmV;-0yF)IP)>S9ti-HZasiwT2Zq>OIr z=IlZz8_bQi*}hUMa6)amu~;i{Bi6px`S-rZZ7iJjz<=*~-sgFK@Bi$aBLX0zA|X~P zl~X#M&aY4?E|Hw2dlj)Nm1@FZFnDMW-K)*fpAcC*L;d$fi-$F`?lc1IcXncJWCSk<24EW;L|87zUVlG!dwa1% zK<4&#EVQ&>MJh#{I64AI%VhX5K90oL7`~5=B1T}*;bH6%P?&&1eSP>!T!p&2aKN(v z0(?Fn%H{I0DwRse<#K{(&^1o&|SzZ9pdrYNLzbK^s&!i5r*(@Aa&*1l~ zTL2l#YeYyAMei}Ns+n&BK(E)s;c&p^ay8cc419OaAwD~VpN}O7-xg!-vJ@6I^F#n> ywOTj%jB%3QYHncV$|+)70`s&C#=Ghio&5{95~Nu0qnc;{0000 z@XyTPsyR0SRfgYWB;#@lX7&;LFB_CN(vlFNpK`2z!)0~roDYPN22vGz@NlK4CUscB_jiDRu&dAGht6p$FI~> zSP4iSACK2DG3bwuhMQFMA7DK>8NZ8*v0PLHPeB1(1m?)jhMj;G2*{R}23tucX1lIq zzNa3h4;L`;Ccjbw@H~%TFnFZ4x3{q(bi*@TgO#a%V0{VxsjuK(mM$L(2m}H!7!2_F ze9-IlFpW0BYkq<)S1&w2USMOIK~T_Qx}#b=6hO@?l}g%q-8}@K`7w4jwAfg<2e1A< zte>hd*?tGw#>=Pv0Z_vpgkc!0F0t@UKf;d4Az-V7=&Zn+r4~Zx74So<{hxRcu&17n zb?_K!Lgrf#9XGIQu7mA;8RiY&!ExNtfF*MeW(FUSvNaIxRoHai#0sf|nm7H6(tV)E z3}0mmAjTbPwrILAGf<1kZ%tU_%Mq|wz-xMlxz(OF(|4Fu*JQ_7OwArVn5X(bJ(SSusOn}JF5z(;QjVNh};HlMM5^1N4#l=N# zS=O1*x8`|y=`lahceoJY6E&h%#wk*-*OANRpzAtv*#&H^K0{YH0rTf3oRm4~D@Szo4obB7?WV%I}Ul zsL@;v5;B?C?ET_fc*9Y21$M!$JsOq^*;kqfgZ1S!*hF#;olA&QQ&S^RsZ z!Dvj@5{+4Gn!L@-#FEX1Kp=p3B)&;c$9h^CqeV6wOLjX`qiYrufW+>$0PnN2F|E&SS6qp0`e6X;{(~1kH^D0 zhx0eU<#Hh&kEc{D7DF@|Wkd&^qn?z2NF)M}$AgWH4Y=KII2;aKosi(Nx*9)Y(fM_Fc7960CGx%0 zJTTLN+opEhG`65ee-V9#R*cN|$(D;)3QFs{8j~^5q1mCkc>Br8aVn@h??$XP~qz j9lZnHOfHwp{nYy#Q$vKsy(sM?00000NkvXXu0mjft$0VR literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/date_link.png b/base/resources.pk3dir/gfx/icon16/date_link.png new file mode 100644 index 0000000000000000000000000000000000000000..9f0aada7140f32ce4712e2b03025da8edd62a6c8 GIT binary patch literal 764 zcmV;Ru)A>AdQ$FlwxQIMIuQLq#R2`6HmQ(^~UI1 z=C`5Bp-?E2NF-A1!*8QFaVZ-NdW*e|j_`J61;0;Ep>1s74gLw+l;dN#mY2~uJ40`M zUD!OjZjcNl>|{|CSZp>71_Mmn?U*zgVV5MKW^yrGt->}rGXwJwm}8~k9cEcZu3Q#Q z`C<_ofplhP(V3pcz-&e?pBJ`Vp)dx(h+_%RY?S@y{5*=C4wfjpo2W??p!fUesw#fb zStfm_X$aBzNcJT_lK-#ZgVPDW#R9$8gGx>sD}k8^=>5b5ymT5!mHT@<66m;!bULl8 zs`{$-`+fcC=}9OHzi|x5%6LJ#-7d1(EIb|$N~MzEetUb1)z#I}$j2hR1i-dGKq(W2gKuXadIW8R0_>z6C1Q#GBvx=XyBBV&FOT0dj`Ocl}ZI)HaD@iw8f_ybVp>h{H}350{GgG2;``m*9heF= u2qu$BWS*seg72+XOH{x#=&sT6CI55DN5t*xzxdh4vruFz3HIvUK)W=dVA z1o40|dZg;=BsS%8?0UUYjIPu$!FmrQ=#bRL0 zW^8nKBi`AGcv~BS&COs;rgDt*dw&yrZEwfw@Gxfj`{5cKL}Xw9(Y`+H_w-NE-^wtn&EU!_>XU`YVWUJMR z1^XH-o(RH;ETYK*_{cF(vQ;u%Hk^yuFwI3u^hNq9s#nu?Og`bvkS04)%_N@TrQ;3>2FkW`ei1Ll5n!` zNhKT%5dNIc8u^Izie_;dQ#_-tWX zI-P!8C=@<(4xcUSPN#3Z2ta*tr~b@E06&A0H#Uw}hz7xQ1&rT!GnahHABnXf%pet0iY23wD!ZNL2O^w!J0B9`u#p^+C1$66v3^K z3vWMOpwzu#gmp3=homj{V9!jrsKap3jSnX_o*aI9sfxvQa>bKKlc+ WlT<+U@H$xl00000x$iEP)-YXOeA2OND zefrk;?i5-sm%CFe7T>cE-}!O!&{P!hgS}Q(aAj@|t@U+yi;Eb;iLfoQx{8UJ8GPT^ zK!0ID+R{QOszSm}MkE3w7K7`$7>dU+7z!b-suDW6=)=R(HaIc@{gjwv)zdR{O~X#J zDV?hIIy@q2kB*`}Gz3@Iu~V%|+fJ<(5Ww%T0eCUWzBxIGdb^Ej%ATUuR02w;6Mnm>~baaII`Fa1z15qy`;NZQzJq*+2 zXJ==TN~I8uMnRba_(VYkZ$FuM{(2W~-^QC~H_>Xf;4e$1QUNUxs1;d_bFP0$u=!2F za`_7;5@EEOzyB)JG);Ikc@922Jd|ffP{G|NA0I52JdBS;pwYrOoilcJ;&y1YW#(iu z$;%_F)9BTBpsEqZt8vP#sRFj;!0lKvc#&3_3G(?o40>A5%E9~l`vH+0qIuAL*s7Xn z|FmHDT(~_)8hwOl4_I>roOx<$3cX%WwgmsLdi3C4}Mrzlg<+1Y8PEBfUp0jJpx4B>@E+cy3`^(Gw`Mf+2&yxZm<$to~Vpgvg&QKNR z_f#1(r6svZt%iF?s+n<8X?B&!h3g9Dbb8_=MX}!;HiQSAh`bp^WMl~Z-44teO7W_Y zV4thSL{h;rJY7!l3%5J4H1!tIzB`Dv+YxO(haWeausGZYkI8^hWj6mzo=L0{%;yxzh{5!Htr?51 zvG|W62MzC8BZ76hRpCyO2zOn<%e)K>NHge!-~)Ap33OdWw6hsLYbCxGNt0%wk_2z7 zfyYvXheSG)5HRK1VB~%mq7Dmurw#bi@hEcOr3&G1ZiF*$M=&9nB#VNf&Q^r$4G5kp zTURh&s)E0%5&hyVD}sp<72~zmAY`Y(9aqO6CXF%=zFHGzO-A&I(pE}v70YQxCPJ{Y z4L+?5-crdLn3ZRPEs!A4ehEY3ZRpL~w9>@aMN+{F4dI@v&>(QDHQum!mG~E^$OS8l z!7?%Uwib*ROP67Hw`ika)gX-(8Ia`-u_IEhxG7U<13kSsMW+$lbb2dUMm5p6pa}cjgA+U$^mJ^AjD?&bdi)8~y+Q002ovPDHLkV1g8IMc@Dc literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/disconnect.png b/base/resources.pk3dir/gfx/icon16/disconnect.png new file mode 100644 index 0000000000000000000000000000000000000000..b335cb11c4d1a397b307883adcfe1e00c4cf8e6a GIT binary patch literal 796 zcmV+%1LOROP)h5&w{Y-QlBkdy7eSyz8|k(w=syt3MbOGZFmTy2f|dnI3kj6Sz)H!` z%1hM3FiovS8#Qs98Rxs5^PSs#9S4da6*};44(Iv3@B5rb3BwQ$Is?0$0ilY#Q^EELL=6SfS*Ly93GR<|lPYvfPXoM^)HN1)!-B@N5Zi(e|Ge`rl{XLurIiz-D}wH~H+MJzd|s z^YP1Hc07G_>)Lgir!F1{Qn4GcTg%?koHo<=1qRN{}nPDolOeI^o4N5I>! zU$N=L=sg~ zDx#dOA*B0N~cqPsWI(^rbbkh)DS0_H_UN0C4l_kvWIm2#Kyy6%BCh z(yIUf003&1xdx>t$*eR2ZvXxT0001Z_R$y3Iju92q*wg58};}zm(OaAH=p|y0002M zh5O5#fxp|~jc?yi@+7$`d4Q6Hl%z;WiWG??NXR{Hx%)pMd~SE0000OQI literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/disk_multiple.png b/base/resources.pk3dir/gfx/icon16/disk_multiple.png new file mode 100644 index 0000000000000000000000000000000000000000..fc5a52f5e4a7e8eb54bcd59728e88a2db5f046ed GIT binary patch literal 691 zcmV;k0!;mhP)h|XiB@gI zjUjC!t---iaHXP+)r{6Ojx+c3eOp)#T8qGEea`PZ=iwYN#&8(f07GMovvqMO`yt0_ zV{GIqh=SUrg*L*EVuk5U_QA?{|KdLZm9oqA&I{b?sAXd2Gmr0G+E?`AZ62*91#}$* zh%tuyPiAI&x-YV_mTQj!pIA(Bw8r7bRXMZUbwz}06c5|lmvZ$Nsq_x5imrlk>1*KX6(-bq8O z2^19ECQj9aBx7KUR8RS!t_)7SYimBz-4JgeVb>Gt0MQyT5n9SDtu2!)2FyRdD{|O( Z{ssThAulbFM%4fS002ovPDHLkV1fh$IWzzO literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/door.png b/base/resources.pk3dir/gfx/icon16/door.png new file mode 100644 index 0000000000000000000000000000000000000000..369fc46ed259191014664e8a16bea76e7513f8b6 GIT binary patch literal 412 zcmV;N0b~A&P)%thM>W-PO4z!6ryTDvQjnlZlgy>*`kliP$?n1x#3mBv=H* zZvSv|{Wk%bFo}=%C%C=cB-|2gZto+r=@*a)F<})kF(DFGf{cEF%qX{I6ar>BlQ09$ zKtwM=E70{BMdbz}7ZEfCIhx`>6H;PlIK|!Y1xVX8?flcwAM>e&;Vo+vaG^ z2pyX9GZt*w3IyWpBqouZ9TBDUCjj71ahpsggwSp?!_6p~6Ug^zToTz0k=O|cA@C)B z=4SI+2S7F9CYUB%6Rwf$PD%xpU1zsvH^-J3qhIec&_95xadrGMyZiUG;F`#)xFk#y zurJ!PJ?Af*(aYIc}SHy&e#bYkLxyZiN`;lMHCXuWKOBa9QbyiY}R8)+l!c;Lu zGC@p$z~K6Ij22J0)wsbx511;JB7MDISvY@^uJR9Nq@bi~L`zglHEQK03t2do(0Qs6*PW_{1G!HjEs!rv9U46 z$HzPJ|EKO<)u6Ypk6L#x)$Sg;sx@Y2o4k8D`Z@f|JD)qaVu_iqHj_a!UF&Z3Ql+}r bBu@VX$p^JhV-$eD00000NkvXXu0mjfw@)|D literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/door_open.png b/base/resources.pk3dir/gfx/icon16/door_open.png new file mode 100644 index 0000000000000000000000000000000000000000..64bab57ddd0e95ad9a73a3828ec29b5d0b4dd675 GIT binary patch literal 508 zcmVjv0zFqT|_}Gg5c7fH`2AZ7W59X^b!J!cjQKk5f=?+6Od?2ip|XV za}o2aVlr?zXY)SuzK59<5o~(S-oAM4Zm-OARNqAS>D|jO?sih$KIXi4#zC#p8KB*6 zhr2T^Gn@5ikAoUcb$HCpdndR#asC03%nV>=v|23yQc6ob;v>x`Pk}_f8e)=(a71(& zuqvL;W`>(lMgvR>P$S&_bg(E|oK*{Mf@#6E0Euv?l<^#(s{aI-7D5%5GI0madt{~$%;b@oK6JNMtzMm)GS2eE@_I zS~TaE^z1tT1me$mOd>fuB1*9ukjYHe@2!~sjG5tP)N7xSr3G9P+3oKa++V)SLaGru zn`QvjgqvWRa7{oUyOUDA37GDE%9f3r>9Muk`Z$59p<W>iYj7vxikNWw_8sK+%_fnobvCa5%KNOO6e%CReDLPLmVwdHp%H5J z8cVW-n2=oPDz8D+5J{LSmLlCXMPg`l3MX6KVJNMw&n~!g&9zA<=CHFVyLz1l^k+DTiboyDIuKD~MJE&R)Oo;bO6gPHCylVLL*a<{&sTsdkI7k&ZU WO{4dBd(FK70000k8yT(1{FYQ%eS|; zm`o-RZoVTR{e-VIhqwI*@698e;uMa`17cSLjDP=8fDVU4RsnS8Z94N(YF@*3(F0$4 zfa7WccWVI`$$I$2KUI8TegR;jN^7ao%gZYfmZXUHr+K`!3i#+L;%mCJVqO6-QJb`Wzkm6y zdWlr63*W^xBEov}S^$&R>(#p5?x)3Kp>&7LPwULD0+^gmrwKcHWY#OW8%2BFWlgZRE7!1(s^(^f!rJbe79GNxG aJ%0hDwGFRvSa|pV0000lQkd! literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/drink_empty.png b/base/resources.pk3dir/gfx/icon16/drink_empty.png new file mode 100644 index 0000000000000000000000000000000000000000..a40211ed412d95be06d475239a37c35fea158538 GIT binary patch literal 433 zcmV;i0Z#sjP)awcLgG1Ps>cqvbu;_Vq%$)JuarzB@HWl1!ZPF;C7L( zfnnMp{=@G#I2=L#pCCC))^Xy>1k(9bGie+eiDo<>3#hIg$F>C#B&%FfLPtmE4jr9a zG;-_{Q4m3n>C>c45seEj&?r%+MTanmAQ|J49v^ggr_Bq`JW!*DM#w+}NzbLsGCexH z(&UkQs(hlcVXn_1f*?uzfvMA@#REld=}z(wK;rh8c|(_Lw3$2sh-%+83%t?gYAR0w zBx>IpebHxQ^qXe@vKcLNP9XT_ljCh!!_LrUl~Y!8E6yeB4A{0s@_S@RP$z*(3_rfS z*ERu>_6-ID8Z@Z$!T^IKJgo@`D=KGHs4-;769x8Jz^zQ(5VWl+{_JvPk$HSoZ`Px@ bZR7F{-p6Gno?>^M00000NkvXXu0mjfT}81Z literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/drive.png b/base/resources.pk3dir/gfx/icon16/drive.png new file mode 100644 index 0000000000000000000000000000000000000000..37b7c9b27d39acaaecf06951b024ac08afbfd4d2 GIT binary patch literal 346 zcmV-g0j2(lP)`6pHR4C7- zkv&QTK@f$%UVGNSAB4p~7X&kJu`rW(3s2w)1kd9QoMeZ&fx$)tn+OJimk zjCT$JD?{UrQ?3~v=-g&C?-zWP;E3TkpyGrhTDFaQSzpwKU?tq9Uh&CO=Y?-R7%>t` z!bl_(!*h(_r3OLS;FuM!k+?!xBDEihL=?r53TBrP2>202N!*Y~*dL6MvS5Ku!P&n9 sT@vv>?encL=G!4ixo5^&>-PTUFAyGx1U4B=kpKVy07*qoM6N<$g0$g{=l}o! literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/drive_add.png b/base/resources.pk3dir/gfx/icon16/drive_add.png new file mode 100644 index 0000000000000000000000000000000000000000..29a35d5aa8d270d0cc2e2fb29de8c8b5a82022d0 GIT binary patch literal 623 zcmV-#0+9WQP)JieWo?|tumGdpatSl}!}!5N1pKRTVx zYtQov9GK7Nn9XJZrqgMF$z(#YQ7)H@#ADO~CtouR!$~HSBI(}|Zd2EFIF5r}uUD*8 zDh=U)D?W_J;}{GEFikTcg^Bdt@Anal#gNHlNOYYqH(0CH66%RW0;AFBgk5Tdh>S6) zsw&i@(I_I327D}hnA}^In5vQP$D)maB4FVOQ z0hf5YdVgCqA3E{(5>wnYI+BvLk;4J;Fx*1L!MP-8z)TFztX+(o=;@1Xf{ z8zaR&EeYiS+`6&~Pw{a1dUSK7c$Mb_%(D;egYqi>H=r0SR#1Hd3 zbY|nm@?BBzL2(N&Tbo$0>hYiWzmcyj9o@cp-I~M4TIne^cJIJaO+4GKx~F$XWFb(ha-_q6-cG~B>a{s~x5BE5t9KSg>n~%S){RQIedSx-2#tZ-e002ov JPDHLkV1g!V6x{#- literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/drive_burn.png b/base/resources.pk3dir/gfx/icon16/drive_burn.png new file mode 100644 index 0000000000000000000000000000000000000000..80fd79f982e772844d58a90c9fdcf751c0181120 GIT binary patch literal 608 zcmV-m0-ybfP)tfHeA#B@4EsZ>I@+pVj_wGl1!`;fAZ@BPyc*{%{DQ6l*Sduq6YK_q`$aad3fgM z_ekw|u=PEl%wY6A95^RJ9cwfir`*e7?3P6{#i4zSea*qf&Ng&+6F8!a!yEs&#rMg> zOSbMY{eHn3+8ew!u><|u0$y@(gU6WP*mpM{*FPp7qvaX!cXz}sg}~)M{7V417_C?E um_6W6ZUPfY#aDvu>=s~f6Xp literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/drive_cd.png b/base/resources.pk3dir/gfx/icon16/drive_cd.png new file mode 100644 index 0000000000000000000000000000000000000000..1850b701cf20400207e7c4ce777940ec1645f43c GIT binary patch literal 734 zcmV<40wMj0P)D#T)oK}@`dJc1(dv;c^7(ug?CMS@EEn0?c*sF z3P%K-mYq3^jLc5Vc7U&qeYB>sSiC!n&6bXU$Aw?*ANcTP2ld^3TsrOB+sG!&+U=d3nBC^}~9=5(gAg^T*vPof+XAnft!b-uy=-!z-7P+jc zv~mVcbAF0*g7f+PkE=Ip+Rv11s(S3Gv~3AI6Wa!(4~vFDNf>(bM7aita;@NCt)OQH%@Lt=~vM!s(GvByx=5c=nMq9A|(cadvYV nf7)x?G!(;T;jb-r_;_P+#g$MH7vfLQmHX~h5`qmw zX%SqwFr*kv!PKM2!+a za=FeGc#O|esT54pL?jaNK|vs`yWK95$s}}LC(;csU1yC(gR`g8X;_wZPA-i?K*ktk zS?27CL;|r`4Ap8C?RLAU5IaeyS*b`>Rqld4sD$ElI>l%-LO!2Iv)SBGh-o++qTlcH z0}@4am=wicfoP;@8n4S{vxF%q#7eW0(+6^D zK*hm7u-N;I^p71#?@ZXq1st#5=VS8*0!W}-F6T=oFy*6rAF+f3tUP>zh<*#FUu)Rg z*}{#Z=vf2$17g0QT){rre2<%@$58hTVEZNJ=2N(?Eo0^T7bxC|Rx6dtTHu!XQTW>L zL#T^7aPR5gEBs;!^Y+QvP5htL?kGQ3*B@Mq9elv})WnIGJGNwe+ehz0k7@48)wj)0 z+s?016qX#q(SV`dW3EU2nqBlc@2+dlhJ(XLvdflTdDin#Z|>HdSAPI_FMg8I(Y~ty O00008>xgSt#M+4&ytoi#D*N41Z+^B#|P?m6e)_e2b?4zY&OB_}=DAs^R7#8!Y=OY%G)-&ea=GZxpJUOcs;X$US{MulrCP1l zj1&;#EnU|!8jTQ(#pa+zAg_nRAu^c^^7%ZI-k|NK=yW;}dp4VeX_~v_vK0mjAt1|g z#GX#4kxVAhXf)98_e%=1vvl^#hvM;g6c6fKNRybU<6(bF!;fGm( zXAbWw%ru!yU>HVJAZ84L0Nc|HimNAZc{zn=uZOsK_2jO)JZ>3y5u9IAMtJqZ@6xbyTAC>K0R6i|e-w$hhSe<|P&aDrLuIK1~Z zY~O<{sSJU@j%f8L}k)_ncR%Yp;$U*>^^d=_ENrHe3iQt_Z2vVu}yz dAF*M&_z5zVZIKEdNDEf2-s&}Y^ic31co00R|9}S-FA@q~ z1q;#;e^rr&XrtIjwGF1}(zLNg!zP<;)}57vSQHN(80NjleBU?o-Wz5Z26kf{c4@Zy zBArgpZf|dgO^2@Qs8*{D*EFr+l}d$TEE0)~5{^*|CitW%it(aPq3QK719D!Rt zgstUQNX^{WYy>KmO33H))&)^=tyTkFCPmsiYYBvUG&l|%N8$5Fh)jdi)eU#&9vcya zNr{LEWVU3L%yGY8*w?y(qr)xm^p2ylHVv_jA@g<-Rh>ihotZ|e)GIj=)SdPn!V<=Y z1$g?-qMW+}CVYe7aDrEJsO+D>X32n!2504-Zjlga{h}HSj&$6nW`5U+~3(a=n wM2C8~*KZr{mthE%IdwgMapK0pmw!#;FKVxMw^?5FRsaA107*qoM6N<$f)5QvuK)l5 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/drive_error.png b/base/resources.pk3dir/gfx/icon16/drive_error.png new file mode 100644 index 0000000000000000000000000000000000000000..309f63962c0e70dfab9154b1d241e63a7a70ac96 GIT binary patch literal 705 zcmV;y0zUnTP);h;AU9E{Nf?}n4dHXi&Fj3?{Kq#TSk zQPapp!o`EsHbz1ei)l$XP&pV;1eRsjdDDQc;nqpMyxGls@B7|+Gt9Cq9A`;5=2AwR zYPI@yI2F7lgTWZOu8-00_bC=KnM{g!j7s3-%XYiH7z_r*q5s$6GHo^+ip3)8 z^?E9s%@%|Mu6SS5G&Gw{I2?{K=`fM@jYb1ruNRR>ghZG5?*c2A%R=4n_oLlzAF)fN z5RowkS(b&m$K!#^Dd%^s_SSPi%=8=Zns;wqy$M)q7NeRl7wYR zI+*ZTt&TwA61=AtG4<&g?3h7!7(h52CQec!RjQRh2}YoAm9-Ie?!gn#Fl@iV>4iJ+ z>01~Y`gp`5!H7hbW3d>b(I{qTBbX1hFf)Gx=xw9)bPaB;3$^Q8Kog(@ zqtOZc`T|X#g2(rVtMBq|^1l4uL}ck628C6eoK6duESJl@;k8^lbjvW%ySU)n#6s#e zRNH%)dgI_SFdJl70{c4>)?aR5v+2*XNsnp!@zUME-1SGHb55>W;*NA|z4(kodJarJ z0XVPX!;_WomT6v@n4t9VVk3TQEi6lWu#6vc8;-m`*?AuOm5=!P`oVK$(hD>Cy1KoZ n?ph}A1#i|rSmOwamKFL7N2-X}^&G=H00000NkvXXu0mjf#EU~5 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/drive_go.png b/base/resources.pk3dir/gfx/icon16/drive_go.png new file mode 100644 index 0000000000000000000000000000000000000000..fc53379efcda49dc4b2fc0eb7bc12bf908425a53 GIT binary patch literal 661 zcmV;G0&4wR5;6} zQ_E@-Q5gPaa(xuUD*8Dh=U) zD{du|NeqWWL?V$HXdX!Y!C-(yB7saML!ujex*;{2O`)Djr7#|kPuQhW2q;Ms0)c=~ zkH_PP#bVGj4c%_H7$kMFPPNjeXf!IqSD$x6*>zo*ripw$k5;R-5hNwUFfba8!~yx6 z=rAe!W9?@Z6U#s;`2>;BIVg%EToOTn*l9o@UXrjZ%kl{a6J?6!^cr66Z{p$NQ>dy+ zm_m?Lsa6Uipdf-Tsn=YYU!iM*@iq1QD%O^6;K(%ay#ENB>Pu0!An<`?HJ8hY-2KIH zcfAb9D}@EUQ{QK< v0Jmp<;WRC~B^izzSeUp@_IuU)>d*fH-<_8fCSRm-00000NkvXXu0mjf03lk8@*o6WkjbwgV1sRJML-eYFIZ)SIxWm!0haX6s~?x9+( zzBf%XWdpgTa7&F_X!pDUVSLcJiXv>n%kh5hv)VO}6Rrcu*>p&}cN$ z*=)AxD6knHhe9Dpk_4a6H%^*Nq;s>`geZ!L#bQLdWIq>KxmRlJO3asib}Wl10= zMNuHjvNIqG9*stzVUl<6VtW-=pfBJA{vDXxH?tGP_G@_N?1IAz zxY2L>-wnbtbW~Tik=vSvplMnmpU+>P_{$t0<+qR!zvIl!JFxV(U}hJeUv*)2WbpQk zalI$JMDWVR3!6@-^ZR^0hgrbsbb{mYc#Ff~ zaEq6h7tG~UDiykfVW_fn~}VltVi=>K&uQzDT-rBZ>xU=T^C(`9175WnkmI+)F7 zAd|^%P4|tsAB{$!(P+T!b|dH$dtBz4%_gB63ncKeA(q}^@@i^YNr5{l4F%)(iC zhG(AVL8Vd=OB@i!>3F~bCW$DEM4|@4j=<;gCrG!@K&R8ea5$_r8jZG6 zAQ>OHu8Z+_49l{Tq|HQHk47VGZEeBxJR&`iuiLEK?JD+ME{ExK`kP#`LWztq=(?`h z9mhc?lR>N1!eB6{abhRw(fsn76!D&H|3dpiyy(@l<;Q-O67NiUbn zY9@U89>6pWgno!vw!setY_1~|TzyXp&<6hU?M;q=Spa`EfKdc9r) zPauILKg43Oaj{sW^Z88o;39xw7&IDpQ zluRb6R4UPOxopepp_oi25Ak?>TqqQ1zu&74SkNwrLI~0{O;tBdlM;yp4F&^RtyVQ% zzNeE;r_~z~6pcoeaCLttIB&Nb9gjyUm&-Jt&)Yhx91aKC?RI3_wnu<)2Ot3`0$bO0 z%49Oij|5dzp3P>eRVL#Jp-{+605bal3|!t-b^e}wK2N99Nd-fY6h3?@&jB`ku$iax zzssqrikyIF!UN?uYaE8@$J?8@%;1CV^G|G XPW_rzx-w*Y00000NkvXXu0mjf+4B7p literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/drive_rename.png b/base/resources.pk3dir/gfx/icon16/drive_rename.png new file mode 100644 index 0000000000000000000000000000000000000000..2a9f38b447dfe58b6e7e4f4dd19e51c606c01956 GIT binary patch literal 494 zcmVs8_uTX4Y-kx0Zb3`2sxi@(iqI1I;eFrUw>rfCj@fm`tmI1lXe8A$nG9B|)eT*?LZDI#!C+9TClU$7<8j!wjp=k+4X}DD zm6Bc=6pO{A3KM3tSWRjB3u3Y&vbW!FM!Ds*80#CD*ylh07*qoM6N<$f^*j1_y7O^ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/drive_user.png b/base/resources.pk3dir/gfx/icon16/drive_user.png new file mode 100644 index 0000000000000000000000000000000000000000..0b4751ce423771231ff45a8703c639e4f06ad7c2 GIT binary patch literal 712 zcmV;(0yq7MP)MFsn&r|Epyjypv6#aTeRpe$bx~OS(J+u ziKs+K&9O<-nNg&9`o@MFKSrPWdgqp6fvY)iIQPDHf9H38=iJLll7yp}0!K8}Xpzh1 zB7?zTS$6dMeTbqs_Fk_y_HMUJF&YR2{Dk93f(*W_(P(0JyPX~S-zH_M)oR3IF_cOr ze=rz~vI=Cz`xc7@JkLX`)s8`vKw4KS6_`vWxLhtGU6DUWxlAU**lji&8jZ$3<&qQv zavTSxQpwnjMkDlkJ;LEI3Wb7SMeI~MX{AFtosRj4z0>L7?enKNOufY6P~KZl;o99* z_+_}f9qy)>v zL>mIhl32+K#h(fDsR-ug-LRRBq#I_(G1P@T%yKUXt0Gp?N=^yLDFLyQ85~aB3|xnP zMu&s?E>s2^Uazl1{5xuvU<4$P*Xw1GoaB7itzk16$C;%in5=Wy*~%j&=x|d0KTbds zpai4Qjrx#Ir?ItNM092W@wNAuRRhI?Su`ar5{U$>nhS+OZ)7c3CT({sQJ54y?Thu~E`U_x6Nu+_cBE@$l?6fBdTRU0H+XuR5x7B4VVArq=3l>9ie- z;>Z5f$7Habi0|)YP_F!d)oO*??Pg$)#{+RNM0xWw^d@6UH7$W;b>8NF)*lrM-)}Yd us~6=;4J0j@Ob#l1ePdzK{+P2k^1lIQD~Yof+B8c500004{FP;YV zAe~^`&|0W3;HDm2rM4TZb!vv~wlvL4?Jtm$#e;!|=lT8ed_T`iLJbB3*q^(v7c(<~ z@PkSILi|{vuz&oyS#LG(Kgz5X?YWd4Fce?AK6Cl$oNs|W?7Q%_dj{R34t^+))r}9r z?c$y1ryyf?;(5RS;jA~sHgyf#e}HEPB3{y4h=#(9*Wp^V=QH+;*|XDA@8lXhS_&I` z61396N&y8py@JBWZ+Fp$2XAycM^r8y9CO;iJn^fXJ4Zcs@1AcsZ<8L zKSesENH~&epvE{HeD^><+(VoL>bt+_LZL9o=kvlTz)(Eza5&P*WD-|AS?uh;MJ7b! zl2^mrIR!V9Tlms`kEPT-WV2ZW0)cccmrIXEP*rus=kuZ6ZX-NCiHqa6P~2XFs=Wfk z_VKaR!i}j#@Le8_Mg#G99QAsAc_@8BmCNOMp654Xu^2j?4*LE6$cA8$&rDGiXqpDg zvY42dfYa%OAP59@l~ELBB^V51=#3`Oefa zrqC4IA@)(sosif75R%{TA62p@n9C!vb)m!}k;n+JUMiIq%$BSpS!3&%mafPy UGkGjIO#lD@07*qoM6N<$f+^-cqW}N^ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/dvd.png b/base/resources.pk3dir/gfx/icon16/dvd.png new file mode 100644 index 0000000000000000000000000000000000000000..9d94de5df00c518c84b400de7176f15843af7f4b GIT binary patch literal 764 zcmVMI6@>P|2u(tv7b=KIl+wsgV@<@e*jCUY7=e;6+2+<% z=39E)&Y3&g&fIj=+>6`P?QFX`&qGIYeyIZ&_j7LU>vx{}ex9QMp!i!3hoiz`v1q5J zrk2OX#(tU2=D5jZ;*3V)&^yD>+0y!>h12O&N@ks8&IN-(#9}e*?d>6x$sn0b!tHip z=;c#!Sl4IJY6i-V0sff3@H~%Vv513%0}zNH2#7|b$mjDY=Jz4)bFfUm$BX9=Yyo#%fy_^Vi~$?>=7ebQy10Lgqx+IAtGPE$iF zm7BanwY5CZL_29lFjQ zCM5tP8H3V#SK46~Hk%C{9UVGFd3ibhRb(~<9FNE0^ZC%$*0xFk48y?V@xX4kL$BA< zViH545Y5XuGFZRgk3b-RNF;)mmX;_5kRsVcAVef5=jG_w@MD4TQnA7|E;L`+Jpmw+ z&7}Y}T982`mbNgn%46mSkGahVUVR)#&H2WW{~Dre(~oa! zJ}e1wsLs_D)K%4|=|$3LG&-x*ibz5_%J3Ro!V1=Xi&*h2V2O2L(fu7Bo}&X4B2n~f zU!$_RZsh1D4h{|~`=0eqfB0;K@28tW2w>SWk0ox7LRddTk8gBz6qV|#NtH^aJoYp7 z^zhOb?3 uWiDU67;9>7h&43TGxZI%!;-n8wEj1TbK{B5NGa9;0000WP)`Q5?tj59obeby-AUR|b{@bs>~!*$bhSkC@X$Ba2>;$TV}|${4yOb`fp`t(z$+ zx$R;$S<3Q-`M9_C;-=G4b8l|W?V0=boKugO-gw~4@0=g!`#Hb!CITSZDU-=mWH11dn0G4IpbUHCHF@eFs zK{}bl<>h6X7jooay22ojA8KM9(NiY!z5y=U8A(|Gvm||U2cHasvR9sox z10WL2I{{_PS+po_qV9DWZb(Ydq3lFS*(K|qEeIeIg)MZxeT-+H8GK>;Ft?&bkM1_E z_8h}0=BQ;~hgkLe42I_4V8|+?S1i@vLXTdI!o~w>`jBKYnS6YF9Kk4ml>rN^zFEwB zeqh!)g=xD9=Ub0slzoStZP?OB0Ds@JR4UEuc+sx^G^~Q>myJRQV8%I#X~%aI-#LVC zZ4J7#)zsWIRxMPJ+Wt&!ZEbmvS|1EFG}m#OF*PRVzfp+AZAR-rJu0M!@k(1uS0<5+ zd4N>3`+GJwH=V3&sO`UAQ^j7sb}?LDQ5r5SKgSj`M`jBf4<2fm!&`SJUH&hMQ6|8M|s4oam`l_?a8 zQJGA(B$Z0HBoawLEEXF@BGK6U$+7ao_4|QZtoE5EX=+?JI5{d9$^Q@V&pd6hSdhtN5R1h?A$GeRKA#WibQ+m-6sf2Y3i$`Tc-E^N z8Ge$#51>0!b26C(9jR0bbZs`95exJ+ zVRv_zLELUP35;7nW*0U~>L|vUNd)@cj$~eRU<19i?SvPp`y8LK0B+{Y*^HqnGALhu2t7= z9|2Hh%?ANJ6=$KSFM_;+i`m-KnBjNh^3@xp_@TD`VV_o9M^CuA{W(asd?n|*u7NIeySlb!R7aSacz5>WE;9^0o}X8BMf<9{cu`u(_0YD- e&Q5Bk^?w15=i8y;o%>k;0000F>2yJ z#Jp50{XIN9>>L~%)JY@~QNLJpYVZ1;fl8%fkg$-1!xoDL4u=D7w;Mj64=$Gr8qEqs zFB&3k!g{fQ-;}&dunm7OnM{bs;|K%-pd@Cq8JnA%h(@D`NBxNSb&$(mqNTawb5mnY z@{WMonS#UNFsLUIiGZ3LjYbdzK}$pap9p$a5DOYGKH7`A$7Nz#K*Gn#wqstemj*l@ z4=u6TY|v`8pz6_R1U{D*A+Lt+B24B^`SsYnyEoI4NLXmKT0upp)6o!hW=dqY+v#yA z=pqGbxK;}=n*yw!3nM_JeO~wD@_N61RPgQ_edJlMPa4rquQ!_V03)E^g z^m;uM3I+Q5`e=Z9udlDu^|4nK__g>DA?pb2@)r1)-y*uEAiKC4rv=oa1Vl-wP&F#0 z=a0dmu0hPNfZucrTVKnd5tm}A_Zlu2{A5s5mU>K#EV&nu_P@g z+nzySwG=^15eTvqgNTC}r4rxFPNbjV##ro(6ZA#m^ZCN*>1k{bR!mEI_&!>N#j$5t zSLVaFT8OQMO6c3q;)hxZ^Ts9`1zlifa65KxB9F&o)IY704U9-I*vtgnYtXjmVXEpN zzO<6NwlJYt_z0)diSF)hFj?&J^z?MbuAiy4ww6&@eZQmr%29;o1PCdgL)mZ|LpKg# zW=agnn;vkuoG^>U5+>kXf<*F99tbs-q{L)RoVer(J5pSbN#vZ%QfK9G+DJHU@A^Mv W{p7H4O;zsz0000C6`ri7_|ADA6V43{+Gs zb#88rbi*Xa-rS3u(~UXzqTAie-S+9+TZ$>sg%9W4!+oA}zUQ990l?WGwOXAkm&=7y zQ&WrM4e|!$M*I%B9RC}p%4rP zJ;dFw=(i$%zfjPg`Iq1iJZZIBkxr)(jYh#p91aJ3J|B|FB+^L=G-ZN(dH}CG>Xq$n zjhTA_W@ZLXBobgAnx?_LTPzj?gF#jrr#27^>ye7B;Oj&$nqOA-vjPHNB+E{P!(kTK z+1X(w>+9<<8jWDalSvwpkP-2)fn7y{q^9~&s`lxVTn>RnYiny@VltUnh^d(ox!rEI zACHBIKu16)>2Hx0#-UUyQC?my;$&xM0GrK*va+%zR-n`A zU^bhfQmN3_*T+Ik>vFkZHZDUq@c>&ZQrH%{VYl0{y1ELF#{({x>th8BybCcBCd?R< zmYQqWG)O>)EzpnLg;qO@d7TAD#|DZ^ZfzYBFxiF8%PMFFiV)izLu{i9e(N|E$LgWd zJMcwoL_yI_{h<!UH6!rXb6HALP zz&_J}xVI0Kr3`azIfy#y5wuNUq4zfO3ky?u`PVP82T33hh!hG1JVEj+*MCB9*J4Rp ziU8TT=xQw@<~zT$a*veq1`dS)!s=Y@-bw82?9AY|Hcx*VmB8jTK=(}u$6OcU9x*$6 zWQ9vgILo$_tpb#L1PcCXucGN>*4|~}@pu`}8tQr;S3RWF-FcvVR>b`?hr&E2o*0N;1=MDdx4(VVfd(+ZMTq zMxvM+sMBSwG<3O3Zn)`mluoDfvYY?TduXCb(1Abi^FBQP-+7+*oRjYdpOO~LJUW5vA)*P<4k9WPN* zlp!xHc<8$dAa5pSr_%}YxLhuf{m94&W@l$i}u&e1VoRsd|PV%JRO$laDX2ICl7>Kl5Eo~w* z6VT-3Bpo}JZ4^L78BJ6?O?BviTrLNP!x1o8EEfJ(s>s@8EZ6j1!28IX}GtKt%RwlH=ftg21UejD!~~WWSAtR9TMn*AWOU+l8i2 z0|<*aH@sm4FDOM62wA@XZ@yO0##hQRly#(|{$nwcB%wH3unni9!s`Edh}WojiTP<; z8j4y|kl&IBUK1O+%^XyA=OMl>1p9Ls9{NY(^ZA0Vt}a++sZVJh#ISJyan%RW__+*{ zz9*NVusautk}&Lhuw`j?CWA!-N=r+bd5?2D8sCXw_^GBL(L#TmDc^%r z&vqiDWIL|Z9)qBZhXhe5{4;$VeyPkO>n;uddO?1iLOVKyfjUmGq4CHh#${#IPAKMB7KAG_Zz-$NU2qgPyRYDi-8^{UGW@v7L1(bmYAaBFzvS(ShGCfDAq g&DfF2@LOB|8#4yVi|tZ9MgRZ+07*qoM6N<$g0=sL_y7O^ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/dvd_key.png b/base/resources.pk3dir/gfx/icon16/dvd_key.png new file mode 100644 index 0000000000000000000000000000000000000000..da9307f66d45c824e1dab3417fc1fc2cca1348c1 GIT binary patch literal 816 zcmV-01JC@4P)_EVp2MD zq8T=|l(FsRwsdn&ZLNL1eYtJ#?sIgK3emyC=edW^>vhj__qiMZIe*9E;$pGUXdIZH zo?g}K^*<&iCVuI3I!de6szx=c(xdwi5|hc4%fd<)PPyG~1Ofqs!(qf?F@!=PSgjVQ z2D=%xvP(0d=*>GM_yfOpI-SU7vxvvzAd;=EE%^O@q|<3+(=-^Gg3&OBr+xS5d!IbY zI}ng36F8Mhfm{s3fZRJA4g`ZiPMV~5kce84No-(h@-;diH)}Wn3m36%XQI(42Sg$f zPU7`?VYAsl>ghCtSjdKC)XH^{Vx#qLW9DAlo#Gr8R(d=hkf11vgUHN8~=dA z78WovGQt65-QM2j>Ll+ForHg>1x#cKz8Nt#m)}4n68Sj+*~CLcLW0!zx_x#Kd&W92 zK@Eat8T_B6aE@L@dtF)Nn1BQi^L59&W+VgSNbE?F*d0P}O$ypA!}>sJ=GX|lh^+hw zvo9MFb@qYYyp6cK4fOXLpzXC-lAcce^Ce!X$cLf-99G9JB1~Ney>SU~rwB0{f%DN* zb3)1;B!xnuoSU1&Zjk+y-gQ{EzQXcp0Crt1+o~EdM-6C7h?VDOu_hP7)Ga{EPd`KkCCG}0W)I%K= u`(M<;>`YHdMsn?pr>eSA&BDb;_x}cBh2mUtnJEDP0000S}P$VM)Y%`)vL%rt*x{`~HJUuLZBW(OY5bH3;Ke%|MO&UtwNcz=e^=WFtKJY&nt z%l@UMrJsw7i^;jUxzP0VwCnAZ>(<}(SIOq)W*sp*iMbey#gIrOkWQzO%jJ+tr4S5m z!!>Rxy>yzV#vDWS*8soGA9r_mQLR>y&*woQ(P$L$cpT+&8P)OyN*5t`R%T$cKK2eh zds=@5pes{zu~-DXN~IF$b2uEv`T0467A}r)ncYU^@&`VBcmq@a{V4_@=9{GLN;aEi zhD;{IAV)_>;5ZIcFPBTmr8pF_LDof)gid>}@<6X{;t{j+;NSo>LZJ{d(LGbp$;k=J z3zsPZ2oPh8h1!O3J2dwYA3$z)#{AP@*(XJ-c+8ylFM zoMgrHet3Au^qNKo8;L})zrT;u(^K^H^u!r}7S&7?LW62Gy>|C~kKjun%z}#^L)zJO z_77lUVgj?Xv#{B0EZ6JxSYKa9V`C#MLsq6)pW870dIo}yPVU+k*4Eb0+}sSi-OgI1 zpOR`8iv_*Cz2L}@sYW}bHA0d2+do6pXf*I|Z9yy+LnstNp-{l#aKLCZvRp)TW51a} zbUIyz{Ya$1Nmm-Qn%Qa;;O9Q0t?f2eS6AWp``I?!ZZ`x10W9`c3}7;u@(eIMJX~iU zG_5>(qDP;mj{zPU^k{8uC6G2qrBW6&Z)s_PL?Ve(0QnD+SBGg}V4zN+l)sbSl~zYz zjAGtBkA;N=xLhu1wOSYq29{HeoX*6^$VifGGkEQ2HZ(Nc=4iA18bTrRJu)T*jV xr6Ql}&Y?uw@m{S~=SbwqyKH-VdxQ*}{|kdM&x8`N2Uq|A002ovPDHLkV1f$qd6fVF literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/email.png b/base/resources.pk3dir/gfx/icon16/email.png new file mode 100644 index 0000000000000000000000000000000000000000..7348aed77fe6a64c2210a202f12c6eccae7fcf24 GIT binary patch literal 641 zcmV-{0)G98P)Az`{eoOom?Tf*9)f$7n8&|1&5M4#i^32;+&E? zC3Q;bRFQN#y*%%=_V)Mfa<$xe^kB0TO;vJPkN*k(2v-CI7)OaWj?&eKPos(H4wGh_ zIC;6#q1B5SMap5{(Hc0~XO7OfqZ=x{kupu8-H&9azl`L1pTuu^Znm3EA)kCoG=JuwsyNLEtY83i->Z~j3y~F)`RA1k>zTES07po!kBVS2y#L{jCt|CMY&v{ zxmqM|`OA#P2{R&)OcQd}v0kt6_Dh#`Z$i5_;q|93je3Q^PcfR{TmBHRmr;rWahz~G z2x-&;d_O~HkmKXt5Cd#Bs?-+qj3zOiUdU24KowBIUPg(gPNmxqX)Fiia~V*$y;5L( zrGNmU;81MA$F2k%oeUXQ@}N%bXz=qOij$4IYk4W=jfhDxfCz{PGXe-#ge#VfYTyoj zh4JvDePrW{lf(Oux2xG;VZmlSvDU+Qf@i=O!B`MLglhttCUHDIKkc7RvVeTifTlZGEZNAHZ7i+XD6HF1R0l=P zfyscSl7Z{b3aDs0m6Ms>RMQy=_$j(NqsYBiu(n~MBTC@sVniQ-D7XOPL4s1%z@zCE z#9N|hjR!nUwAQdZiP;?yq&uRRc&DJEnrMqqk0|m)F^Qn8x?}}ytx;sVA|RXQQLVw6 z-Q)+esR)vZ5Jso+9>FEb93>v#dzD8l7V^#ng}-dn>P-cNcgHd->U2#00Q?OKQ zcz8OiAj99uA_H|SPuZW&3N@X~?e9Wq4Gk3w0(oB67DQMxk;EU&)A-1l*) zwF(-Bfg`;q0Oz2az;d{^L@9A{Qbthn!_By>J%pVcu5B})M)9MP!_mWskZ#$7$!|}P z`+5u2Qa>-D{OhOAee6jGom7INCCqpO8QNurRMbW%$JB@W*x%C&Mj3iL2f>JmzJ2}B zsxKVD*jQa0xIB>v$lMc?Cfaft8sNECd2?0Pr~ovTHJW zhZo`7;X$R(W_se*OR8zHHsnH0(1X6wG?qmLRW8mX3QWjrC&-BgIgP4H4{F0Mkd5YX zg_2gTCQGcXb|K(*;@R7zNic|RhAfL84ObVj(rhejztEEy?Phh8hQPIXFT%&D_;M|!65~o_|==)((s!ROj<^0mjv8#Q4o4cZdw^<0!s>!kTS(r+Q&T!<%0QV&g zIu#0QcaBCa&9OMfMn}lB|3q?Wdf_{a%k)2VbaYTb5FW(i@x0&f7rVN;9<{f((^xEK z{hdR$x{ZuHCd=}H&d$yd%ex|q;;s4ldFSBZVDV4VRt`4A$DK~+WLsMsjYgxE&EJ0k Xsy$=Xcu`==00000NkvXXu0mjfruKII literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/email_delete.png b/base/resources.pk3dir/gfx/icon16/email_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..a9932b1ad5ee05b4aa191ace4d859609098568cd GIT binary patch literal 756 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 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/email_link.png b/base/resources.pk3dir/gfx/icon16/email_link.png new file mode 100644 index 0000000000000000000000000000000000000000..2c49f78a657c1ba1ec0ca6a28455721b20d4ec50 GIT binary patch literal 821 zcmV-51Iqk~P)@&xZvixulsk-;T#44a~v_p20ZGUos{+e ziqz?x2bDc`a!X|=H&x$AMYoNVcg>OOowMZH)34;Je1??Brir-Kni02|lNTF@eWxU< zNk%>3@}$y)izYH)GssfVp3xDiE3_bkWMX`Nts^t6W3>pK-9Ht?o9O^7?i6NLjsQv?P*iV0iU-X5Sd9M&!sd>k z-}n)V&Ti=SdNj)vcx!UOwiJe3ap)x zhTreU^71mwW;2vMYG|~5SX^`qp4Dm_$qtT$Tu~De0*V@+3QHb<@Jz?l?%DX)jK3n%GeMWMRG`GqGK;aY9f#^aZ zOePZ?4hJk23kC-Vah~@swT#Cppt+@$Wc};h+}xV#>gq5Bl$Mr`=jZ3Ai;9XMkw^s5 zntHTH0W_NhILR;mh%Tj488#RUA*0aU)W&v_?a!!auqSM92 z#VeJSmGRoz+9WTwtgP$?uL8c_qaN+i49)%pyygIR5QP`^00000NkvXXu0mjf)cSaJ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/email_open.png b/base/resources.pk3dir/gfx/icon16/email_open.png new file mode 100644 index 0000000000000000000000000000000000000000..7b6f9813d41f1d95c8f1cf1495c2314dcf16d3fb GIT binary patch literal 783 zcmV+q1MvKbP)FGA|gUiBpPKsNC^f4AtjM-BOo6I z6r`2%Aq86cL2037X}jIFyW8#V&zXS`i5Q*a$xLSEecpE_F9(1-jh2z%g|>+>+9xA0 zkA`ml?cS-I4VJBEmYFboVFjV6ilGGo&n=#={}R-6x+aGgB1p&v)GVM86wScQ&nTXB zxV()Yx6hm^cssa#jvorBcDDqH1WO7Kif0)qmB@%>Gn58D97J7@zwm_MRj>bE`@}Bp zw=N%IUV^D*3FYq{D0}w<#cynQ*tSI0c9ar2tzlGk`gkVb2Lt-h!U1+kCK~*&K_&Eg zBa1QAcKdbiwZ-XEGCIUmmSv@bUpq<3R0cN(WOi1<+aaYj^vwovvBKizD$OfKf^3*t zR*wY-2^CREWpg+t!?!14)f;1Hg^#T$ZeGF0j);QBIfEujA4UQ4w zNg^VWy=WTlU;>5#6gAADc`ObgsZas9yG=GGSPAOrw~1)(ceCIa2^Lcs1{H>cG-|sx z&^i^zCubH1(vjd+-8>UG_jIg=bbMYEQ2D`$>W=jjJZN)b-Xmkum1P_Y3Lece!FpJS z!>?lC`#zZ!Ci@+_*F777byLAt?~&jo5nMJ|NvG*p4yY_Uy|}ik{~@5z3VKO`8J7Yf zK`WRCms>h+q)5+>IRvcjsPGB~y!!?`1Q)?g*ou&Kgj7kMY4<4@AgvzQmr(HHo5AH2 zwR@tHqVEVPBc9SA${J~94M{}<6;sj#nUXm~5M|xA5s~vvmM!jVVbes;o!;2_ve8U# z#kiJNIi=-SS+z^mR_#j7w05;_TDwNLUVq4q`svKor(cqJzj!aV1D~<*HB>(T#!&X?LweP`h!V z#f5ew2F#+kh=_`{(2cDWLBy7tHkri1Wb7oF$^3io``&etX-G&e+`Bj&F87>!L{-_T zzWA|n)Q0xwK!hlEuby~r@XH;Es=BQ|oSK=Ky1b~fiyf`hx;lOJKmBOx*5ppyZNQnY zZ~pS#)g`UB6YVg?ZhbEqmlQM~s!=ZT#ob{;{A zoFhq;@h1;+eW88s^ed&e?78U$KQ^2*kB{~9*UT+WJUhs~LIDwr0&yZF>u%v)#Hr6O z@xq}3d-JPrPJB~-!^Z8k`SC}FO5IqAV@F|cf$GPfk;!B>jF!OSY(VC<nfc3_W}hQUTZitf6w{8c71n-2vV^f1S5q93fvQmQ1tj zB^?@`daTGwy+Hz`LksuJ_dS8xX&mZOe^A|Uz zL^d@{{_qFm&m3WNIEVD|XPdoO*#Jg|a-^R=%mY)Gt002ovPDHLkV1h-Zv9=jZ#r=d=hWyU?P}@^H?N!+D;^s4D+csb3rJhKW>ZSD{se zW>rw(t_Xc9oXqah$=UN}_66>SX;I;fY3wMNTr--k1NCS;f-gNFdDT@E;ZW@!9rz94 z`pq8AwOk4o9wZJjJRP{n{DzRK$no}>V__jrL&E}+cikkP2KLq;(930j?KgF*42Eki zL=ueSr;C(^N<6$hhAJ${3x(x^$utsX*6`)d;Yktl4F`2J08pVl$ahAX21$za_Y|qA zNoZ-!uw|RFG(W-3>jpRe1fRU2a#d#}o_2r$K!i3^yBV1-qAq6p?pnTsEn&(6ux0BA zYA11H_eteeBA&Lg3L-R-sYc>4UO%n{lLhmOJgTT0WpUj#Ai;YIWq=B?y6H6DQJ3FH z<-FyXApCh>JX4<@q2s-viU{G43p_<^ybjV-MKRe0D+p2*KLNZ=@Sm?@f=a}vunDhc z|De~7Jiw$I36cTq*AKvKhbngb4Sc>xs(LN)$RKux-m;9POQv3gx6$Tvk=PfwsX@YA z8x^??pq^y-7BlZp6V6?Psou%pl_QhRvTXe^9WEPb_@ddDs^8H)r*SWY6S&eneEb1* z)0kA2FuM-VGD^>{QhM39e?zDC{AT5$^Ja&5PE|E^6w>on6I28s4wrbQhFJN+t=`k@X24nQI!m9kbZt8EmoWWHeFN=fO8(U#im?Cy002ov JPDHLkV1hIwPW%7> literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/emoticon_grin.png b/base/resources.pk3dir/gfx/icon16/emoticon_grin.png new file mode 100644 index 0000000000000000000000000000000000000000..fc60c5e1cd0dfd034d9e755302c9cd163d317a9b GIT binary patch literal 714 zcmV;*0yX`KP)1zIPd!!Rpoyw`fI~IH*r;ZRp=I> zLlsmQ7a^s>^~6cdZk{)rFL2LIrwX@BeP5$VcA&8uP><%8@Rxe=(cb`W z#GKM(=U}koJX*00zcGn~%c#qPDI+Lr#@K-H^8><#(bIM3^idIDM@)?>Gm+MNaS7J& z`83#Xhzn7l{{a!jl-3g|ZRP9O#jFSoJJ0J%0H8u|(9j>(7)Y1~x6a7pC6EI60xzC{ z*eq`C9X|X>#lHTyczOW>013a6 ziYkcELTMF}TV?ufHJAjLU*u6m-3q&Fo&q7>(^v$kkW-hB;T<&%?Nrq6!32@5`{G$& zc!RDDfhrIuS8 z?8Y3h*`bPE`v}YTiB=sTw={z-FjSN=Gid5W_!K{KCoc9qZheMGvWJpn8>lB-d`V&U zCXw=8n5yH){1jit2GY)Qx&5l9{+I=T+1n;A wo<0$}y{E$!z*)wfCFLvwhp+u5O#f2f0aLAAZZV~`sQ>@~07*qoM6N<$g0=}oVE_OC literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/emoticon_happy.png b/base/resources.pk3dir/gfx/icon16/emoticon_happy.png new file mode 100644 index 0000000000000000000000000000000000000000..6b7336e175438cf27c9bcae4669f9711e09304e0 GIT binary patch literal 731 zcmV<10wn#3P)l%u5=V2goM%QPGY7PBv-7BC^0g7Fa2Kgj6IQyYY!iS>F3t^;Y z{`dVv-isd(F{Bofw-%8$vKIg>me+{)A@}VXl%+GsE>t2jcM|EqamZ6;kUSPnE=BU) zeuy6|$S$@a+)Ca8AoGfHhCIrBUVy*v68!x);UCyy{SEN-)*vyqhXD>Owvbo=q+gJz zCkOfU^N3FMBN+)mjLmJb^;pE?#E-YTSlnhTG?QEa@O-`cN-qPdAue>|r>37@WzWyjAHen>@2_o+^B&_t+-Fms#M`L_^0`U`~aor)ql1d5Pg z6owrVjF7Of7j1n54cD~V+Wq~W=b7nXZIaQU<}$-D^Wh8g9iyuJPn7-MaF0z&l@1k7 zi;z(T6-GoDP~qCfbDCc}Z`LYsk4>`*H%xtJgQ?D-@mf%i7IOIIQNnlKSrOW6T6Aa~ zzzv!ft#0lKwzQ#%D*U(CNVtT$BA5z-ik%o65YF5q{4ms7cV2r-06S=ERhf?MznhZa zGrpJw`vq|!>WixoQA~L~vGVh0X>qPIVC$n@kA zgAe9Vv7m|wv0n;2S!@A_bF_Ik?_SL^JGp@R5EaWzcA1Gc%VZkUm>_}pGHl31$w(sf z+uZ2Ept_z!a-O424U9dTV*JG{cuTUO^>-YP_8i z`v#vMN1_$fg^2rkMu;VMV$!FWzJD?AEISTe*2Mszrd1b3X#X~G3v?T?bR#BKi;99M zL3}eC>Q11E<1D@G!$!0px~z-qtUQ0moD|RXF?n)b7)X-x9v-g}ON5Q~a~p7C&aIOn|YYgCp0srauA_td0R8BpPn z2tBHx!h{GTDqKz<)yndDvwQ>h)by!v&Ey9=O|}P3tOoUHEyR~z5ls#kL^zW>rq6x@ zxKVRVvwio1b*ItfDtz?~5`95k9ZV}h>t>7%h(6vSDn2{jeoF5*0d~}^R%JTYeJdqF z8DB4eT|!)h`uY!uD5fP(tfiZ;V`nQOZ0tC#3ju%%1Hs0jlqNu;0=RFCJ_tb?;2S)D z0%9w;@@stbp5)e{lz0XJ0ss+?m|QPXFQBf5isiuJm8e+MTlV)=P>E1m!7aWdp520Y zjx<#eVH+(Oq_&8PrMl#q|D0fPp$$dJroWO)7ikF^s0)Dz@9As;RH&(|C-4q@gW^n_ z)P@t}_jLmhPQNCcy2|=o5hVasM2P)7!BfE2fCMU*g)b}U=;|ezSxYjrmX5AoN=s`{ zX<&jR;^WwespUU-WW!gOL>?8$<*Lk1j#DkqQ7z9gJ2_4^Sp*G;XLe8vr?CwlHDxT_ zGwmXLNcG-GiG52YoFbfyu~<%n3Yp|Qx#SFO*$zzRAkz=eRh(tht_wQfG}8QSb0Xf} zf2TEn9AZnj(hGcT26c5zJWVXU6VE0}Zyr;6H*#|Kkly{x%Ck33zj&^+Z5!-Ntl3Vm zA^>r?$n$OX9iPXB3(j(W&qW>iV-^5DT{kK542p2bdwN_0oMpmUMx14M@1?(l>0jzQ Xr>}D#C{Y5K00000NkvXXu0mjf8wo&0 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/emoticon_tongue.png b/base/resources.pk3dir/gfx/icon16/emoticon_tongue.png new file mode 100644 index 0000000000000000000000000000000000000000..ecafd2ffc542f88ec6e42eb7c57ee253ee7a3fcc GIT binary patch literal 727 zcmV;|0x127P)@Qs&9_62n*m}Y|JO&A-Hy&om}^zi7~6MB0IV8=~|D%HZa>m>>1 z@o5F@0^%~%r{5u>m|_=&;x^`akX^RiP9H-~-}B*?Y=@Dk2nqIPg@kNiRh7>~2S0hPs5$m6+LgMb;RDO$<}@1QWC( zKE!6cS$>1Nwl;~0x=;c2IqED?vnOk$Xp-X=5+rO8uG~&it73ER{s4F`HC|kZab<#N zJ*Yt?qrA$|v}K;RGj*!-bF4qyi59mr{rEy`GcNrUq?sG$Sh#jzw7Kgj6c%vxr}*Rp z>QYQtrcmz1vyuACd(>Zz9p5pmH-C%r^ffaep35tGhPtEGTM3#15Qob=i_@?8_++Hw zEN6F~)3HBx0buH?DT!xDgah8w=W=kC31=B|mXTfO|5B!Z(Kjm{e&X4d%*g-%002ov JPDHLkV1iW*MF{`^ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/emoticon_unhappy.png b/base/resources.pk3dir/gfx/icon16/emoticon_unhappy.png new file mode 100644 index 0000000000000000000000000000000000000000..fd5d030ef773ddbd3f18925487a870ae7679b08b GIT binary patch literal 723 zcmV;^0xbQBP)nI31uuPEx(b2EPDKzMg2IC! z1S@@jQACFdqKw6YEZj=hS9jm{d7haL#U>dYYEHv2^W)FV{Ee#eKT-30!OfVgDx)f# z5TQ>MRCpr7vK;P}hO60nz*0M4#`U-gZXsRsl9|a;nTHdTwPU zDB&vwuq%j*P+$205yhlhNu+vMo;@3i(AGSxUjqOYMuWBsSxtgO1#qk6CyO94_?QRx zKx~LBy}(EB$aG%Fif0rc01#o&H1#8u0_w`BSPq^{qhe8SIWQ2S5}`K4Ej^>AaW~=_ zTo33X)quFA>X3>>U5xtpXKqm+BT*5E@SgVS8C58&t0eIbd`!4p;>FWBO5Z{dM}5Z7 z-Q7SY zRRtnU+2Zp(L1QcF+PCx%bW&eiMtlYJ5j$IwVVpI!Vv~gw2mV%qCO3uhz5jFCglR^LI?Ip4kMsCGM^*WsD)?OphMkxyJu0+| zkWd8`MnxD>;n9Ixn%>>-?4BSPc3M<;;#Bw6I;9CTQVwcSvx?mq!~4=dFG6=&hkn=x z2;Ms#TH5m3J=%p9AHrs*5N{0)a^Mu=7M{ZKUA%=?cq<<|D{t$Y9f1GdDOcrd=)#Mb zxLXXr93+)AoVj=iRGA*%B3=oXub(Fry}iDe-e@Z;FD_(}?B9Za^K;gRD$1?D@#%a+-~0vqwuU8or-y0ZV_*kR)~P8Gy0f#- zK#vhR*o+e@M@2ytHxegYc@-^gWo_auexB~edz#v3<>Yhcnphr})b-XzD$e1CU66pl zvt*JpERXch2R?V3?(5JWvjDL8)QO3uSA=$JNd$Qad`1JGp}?pA(u2Q*>0jyxXpdYZ THlv1D00000NkvXXu0mjf4(Upu literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/emoticon_wink.png b/base/resources.pk3dir/gfx/icon16/emoticon_wink.png new file mode 100644 index 0000000000000000000000000000000000000000..a631949b5126181d03d2cc657dcc36c0f2c3ae48 GIT binary patch literal 712 zcmV;(0yq7MP)(qcS7fXtvA0;;08>+3O7teOQp%zqTvQmk4Dq@*%u_^?FA9et#8o5RRGs- z8Z=*jFWAS8b%g3KO_4M^U0l1vRYZa%HuO90z%HmEX@+J8GM!8d$d z06T}c1obiBW)^t)JmNrICHXBid>uMJFT&34P5LEvxyN0giU_IY6+8uOR1G02mTbO^AXBl*H0onaP>T38HsKXOu((2x zoqmA{D^LOV^%1CB1+X)Nq}LuKnx4QG=~)JNIu=IS=5aZKu$aPt&Jo3_ zUXu6SXvsk)AGXcggpL(P`gF&fOm9BgnW<=m)EsX1DL#6Sx)_trk;+x$*~RQ=FSBEP zrw+C1-Bnheyk(Ax=UQ1+OJ%rmAHkXc#NiUp_sKCn47C@W<>KK>+V{s_0C;!PWX01W u!ZGiubwzNNC(hF6EbTRy|ME=#5eOSYYtbpBV}~vsBnU!_?2tr-P=|^T zED%wc9ezHgW@NMb!^uT_|SvCpFLJylbx zY%bpaTGI8IYXMN$9w<3j9VkA~NYOKEQXsj?6a9_hcwfU$acAhJhB)zb_w@MVUEy@S zX&I>K-R!bhu3?(6bHWIg$HEl7{9g>>&l_qdd+UYb(1~BCo9LptNq&8>!yoJ3Ui(i5 zRJ|XnYBklL!{@$-7=3mJ>P@1c=7Oc79e-V7yf+%lD2!I;Y&nXBZ>=B!5?CB>LvEx6 znI%n)qqi$#X#wKB(U7XP2P=+4{b@j#r%9-K(8UqtSDk>0UKzf*HM9yqMZ1D!$2MdZ zR=`U>0zhOH1XqN?nY@AQqB7)Fp4{v&dKXvb43hZKvnN8;Po;+jY*}~*Z|W9Q0W%{D z^T}Cc<|r(Su=1K=P5>Z4 zg`et&Va}tdzBS-G-ZcO)zCWpJvGQwrHZ`@wpM420ac@bI5~KkTFfGEM3sPWO8co4^fI6lPnA)Y{ef%@{+SnoUk0+dW+*{8WvF8}}l07*qoM6N<$g7cXs A&j0`b literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/error_add.png b/base/resources.pk3dir/gfx/icon16/error_add.png new file mode 100644 index 0000000000000000000000000000000000000000..4c974840e957a8f7a012410b90ff06a055534a5a GIT binary patch literal 710 zcmV;%0y+JOP)0|UoKa{= z&8FsYq_B&mZpt0E>87*hKHb{)+V{Wr9ETXWS}*)~Iqy0D-}9XJoR~5ld`QhI}Rf=kyg=`}az> z6_9YbOIPpz>6=3??LutnEEWbESt4dJveA!-IcBl=q-xF5yQ};Uf$LrUNN8S3D*2Ff zbrXRM%i3cFK@;Lu8FI-LxMy#JR_##yCLrM|r?xJW&qR@l7?7~ZSV6+xhV{>4L`-L( zn{2|(zGhrfoy7SL5v1)r)uzDtw(e8d{ETdz8%bvu5>_b@G;hAb=-4UTd36Cgx(8oe z6x7q#AXZnSLC#e&;p3i}R`Shb;0q98XrPydIV-D^%tSm zUxq-=O>rEfd`H~zffeL4LBfv>vcV0=+KF3yOwj$zREm=3`CK2oDueOV3ra~_rl z55P9C4@*z?V6ksEOpkZMsH}wOdL_E3Rw$?zHmsOxVLK4Yx!IzJX)B~s$7$t$JfPax s%FN7MvwKjApdjfaM3}Y5P)NtNS4FfTR?fV zd-U$^Je{j6ms;sQ$x0W9{2-vej@j?m;OyLe^1lK^PMq$}3&x@WMEwRh-t6*Cz1o?$ z>cF%nuOm281Az}gh&nMld>8cd%-U52h@9bipA$oD9`n;Rh6YFOJ#egzJJ9aSS18Hcm)GW2(nZvGY^a*Dk@ixapIxS$TyUW9VEi<~naf zFm{1`b{2!D6IX6cV&K;Zm@nFVL~V~yKksY`|V;Z_*$Z^m%-M)Z`*z%-lyh!i<5!3<%tf`X=mVpsf`mZDQ^xca3$ zm2*@k!+lW(Yxx>{D3kJC#nh!$1>$^GBwf%HQ#P_}ft=~M93TG)8Pw_BIl6BR00000 LNkvXXu0mjf|4UE) literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/error_go.png b/base/resources.pk3dir/gfx/icon16/error_go.png new file mode 100644 index 0000000000000000000000000000000000000000..caa1838d7f1deb211954f417f44196d131762a33 GIT binary patch literal 734 zcmV<40wMj0P)B81U&hml7ftTkzJn#82Ff)=N+_m4tia#>Z zED;~bI?|((@r+mjthjMa_A%$0tfL-QbPg*LnU_WAg~uA`bk8XfVKMue{f|q-zK6T5 z$+$@!kfN4#c5k}DXoQw#g?X#j%8Ke&msn`eT!P~gh zHx954K@vhr&4ZG+`hMNW>{NV8fvu^oY$D5Q1iV26C?>7a-M}^ zf+7V1!ylPMVQx91B8Cg`?xBTxqe=5WDy=kaC@M|QuY#QKhWa@G0EkNg#f0(jFm#fT zq(fIa<`(Bsvbh3LeZkN_`bKD^)UAxX(*OX?;)Z5%EeUj&Ln?`^^>#>7P)wMLOu%Z% z#{0>)_#PZZQ_%FyFws`rLW<6?B9I~^a*dRT3jsj_aVg-iIZ@^~jCT_~7#@6%x*tZE zq`GHV=^FpWu6ko=kNu#n>&wdlL2&yUSp1p7YT&3fgcO-N#0$9Ug7g~-`rQ^qx~m@y2OU8A z#zh~=7n#Z$Z*fx-GOtDf07cgx0suCz_W(2~Y(0tf@FX@P6EPuM_dgn$vj9LucO)%W zw%HgMW>=#oL>nZ>M&NEf08>)#)k<{$fCT_r>rPi=BV=hFh6WS^qqze>C6Ek}o{M5% za|@JGowu0t{&hgNzySHZxy@LTNh);YzZ2zSp_ zl$^T&Dnc|NLb&RD_!4>pt@VHdP)ZGER%5ZmWEe$lryR&y;2u^3cOkO4#6c%-(EY6a{600000NkvXXu0mjfxS2AI literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/eye.png b/base/resources.pk3dir/gfx/icon16/eye.png new file mode 100644 index 0000000000000000000000000000000000000000..564a1a9714ff37aee1c8758109113e434eff7862 GIT binary patch literal 750 zcmVWW=I5Rl}zuENrQ28Pt;CX(qKOcDU|M8F&Z%jVGSZA7t& zSX&s1bi|{*v*DgAz3ST9+K6Us3~0Q9*~BWe6PID=&0x|wWdf!IWgI(}6lv9v-FpSS zw1U9OL{Ex%ACuJL>=wxTZg0 zEf8`!jsrze5UvA~SqG-HeEY!{P)iC{?3#nq?S616TB~hnMW{0-6j9tLvf?&u+XiC{ z?O_E0jiYQZlqIojGL$5a1qk9N)mlxpmZq1W6gHT`ec`8K>j$jl3}`WfukS z{=!u2#P1a^U!H8Xl5T`7??NT1t zUc_pqB=&-xQ}oxwg~5^6HaUDuDLGXE;y3!@QP_pOFSc-kKKIu gX8xa5{%_a#2W_ovs9z>%07*qoM6N<$f|edvg8%>k literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/feed.png b/base/resources.pk3dir/gfx/icon16/feed.png new file mode 100644 index 0000000000000000000000000000000000000000..315c4f4fa62cb720326ba3f54259666ba3999e42 GIT binary patch literal 691 zcmV;k0!;mhP)bpQb1=l6TxbDZwj&S={?7%qx-u`rsG(Zp`-rh=e^=%((1yvsuf5d=&62Zj)Y zH&JviNS_F4_Hj|T(1j4$p-!}kixP9&dB4uv^MveG?dGf%sUCoc2!IFxD6wHRA2^dX zXRVk!-qSfk(jcaUKn#RP48(whfPlJUpApdrA!TQi_4D+fVoM;3I0gZ8{=Xv~Po;geVA+Em9@0Wq2 zr>OTZEGR05L=gf1T;ucCxq6Q6EgJiH@@-lVaAlQyw`jIF^c=&IVnj|95hHbE_cnt| zTzZQ?F4Ne@(bH(~&3nM%m)I@ID{@jJ2qZPjr)jhpe9hViOwH5k&|T#EmmL3(vHeUQ zq^!t^Al6JD;=mHq^Bg?J-8-zG2Od7gZbknG;K9czYjPqG*xjPo0k(c4%lPXTpw(qq z@aGMnxtFS(np+2kC} z7P02O874ZkJH$v#nCUVx$({yDN`IX@o2wyvTD#e`qN`_w5<}$3F+_TL{y z@MRP|R@VB<7X5M7OKHel5p5DuZd2LP^mcc@yZiO|gzD2e3w_4ri~)#<0Ehs9I+h%+ zEqXIo=rgYW-Z7;;BzagiGdi95D<_xSo(Ra@Z~W%Ib%wDs3!CdlVJHbR%eNk zBqEX^M6!%x7d^Y_IX0F9NuJokZTkWHNjLfP1ZTdWv4KFAA#mwDEmzYdY9iz)pX1ad z3)5__kZA_mImnE!wn$VIw_7&<^lA9oyNc7ih}sMe`f zNgGs%A|iT+dHj9uJH*Y8vcAB#udp};?0$yQ5Y;M`I%%C6Q4l|SsS&cb zW%eCnah?PrkZ)t>0dBa5jSGDIoa4EYZ#K%-HZMxcYew7JJu&^6oF)X4jFFeg7g_v) z*`ss~P%Qa8DVZ&l?c001>#pke-RVz!I)Bni>sArOjP4z58>V}J>-Vz$FQ+EKoZg`pMkVv{y%udh7U8T9PdaStfa-U#H$HMqJrX zp-9Zw+CxW)&Jr=Iq^YUZ-)%2#w_5(&+UBw!=T6$Sv^Eo}59loP8rN$~6LnNjLk$(w td8e)2N9}FOF=%aOMlM%>d42BE=>H4U@GgW~M}PnT002ovPDHLkV1nQTVmkl; literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/feed_delete.png b/base/resources.pk3dir/gfx/icon16/feed_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..5e332b4cc4fdc60e44e5f3a5c2068bfb24100241 GIT binary patch literal 746 zcmVR2Ufr z!QE?>bpQb1=l6Tx_juY4x@=z=P6pe>%4jL0NnK<&eL_if5qT#RMdU$*Zh{&81L95L zO&DD_7+8@}CSp)*WlCA;?EgkB#DS5 z2$7NHSuX2M+-b(b(YnIc}V#wT?hhAaHw`@?Erv+6XC|OI(>`_97dr zWS!jm98aEN*Ek^1Xi#g=%*jbb#K7hfS3e>K(n$9xqleisz(YrwIn9l8)SKjW8ZBx> z5fS}kyzn89z01(Etj+S}TP$1v_Ps*iDD^tECXFUJQ5zBhvQBzNc;IE8I7QbW)9*8X z9yoB6VjHyvjTSYch=9K@^XZ#RpJro~tb<41rg9G#PO`pCslwi8s5NP{$w@`TNDE_&;5My3+ZMQK`iLm%dRncM%eu@YyWU%63k71W9ZRZb;@!wh^O-N1*>(YP6xI2d_Rfq-Kd)d)PS06D7 zF*ASds+dKMWW&FI73P)_-R<_JP=8!kso#WtRc$m;LyjCZG+DIW-1>&R6=X?aXDlua ct+b#19|+d#a=?|~qW}N^07*qoM6N<$g8W@n0ssI2 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/feed_disk.png b/base/resources.pk3dir/gfx/icon16/feed_disk.png new file mode 100644 index 0000000000000000000000000000000000000000..a158c998dfcbbe2f8620b0f54f7a8a6fc3c9a858 GIT binary patch literal 738 zcmV<80v-K{P)`Ew}GIDXe~09L=$a8VrKH@y}8$OLiM7__PonVT>udg01*JtVAJZb=e4pu z@3Q+J>zZArXc0?7AO=Dt24X-#KtLX``F*$j@inDV*X%M?!Q2W3wtwcIbz-E5h!hBs zoSB$nW{H_=-4YZnVuy#%0?tw&@Y@tUKj7w99PH2< z=fP)r>Mf3)0R-xr!n?u1=*Z1|{o#gtCfYW)PYLmqiLpY;!JUnP3xoHS5)=fq#+hDVdcokc z>mEP-fM=E_eE7{RuRgZ`0N(jx$7;GNiU_#9!6z5EeuaY_{i=3*zX5AM{0-o+VXtCm zcPNCU6cHmiGT5f~Ia}X}@th)4kCHdfFG(rOC}d+LRaMzL7%C+Q6qz$G)0&|7rOvO> zVO4wmy+6c2GfL7Z$;dgA8EYjah?(h!IJN@hMw14rQKN`0WWh)XK~7oDNz>GZ!$t`N z2HVtqT4U_|ZofaR6-wuyKB7rOL^3%fowDtXcYFTbJ5U-THyH8hC0a-6Z5X9j6k3vj zx7S}XH8wAZcKUxhx3Vhg=vPCfTUKp;+cmR72cw!3CzacU6LZW??0e$mX_M{aM0O94 zn;CD6wJAdoswYjh=Ug_YE1|(5FQiq2`<6}KHK|kHtx2_zl8{GI==-I2)AnBNe~SJJ U?f9j-VE_OC07*qoM6N<$f^rf`ssI20 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/feed_edit.png b/base/resources.pk3dir/gfx/icon16/feed_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..f1fde7a9ceeb500d97e5618ee9c0deb9d38519fc GIT binary patch literal 801 zcmV++1K#|JP)e=rfe*WBnrlp8ZPW$Jjl(9T(mJHUQ8Ae6R(RN zBt&l>IH@82B_<96Vnjt@==hy+8Qa*{9D{Z1*RJ(>qRN|EGex6fB>({d0096{!>qAn z+Q~RmG-~%tC7na0(u9~OB1A-i5D_Azh!CN%$?UJC%(rL7VkMnJR8ka%Nnzn{9$X;= zQUQS!qClfTa~mB8=r~)7K`KqiGB^Slp}NNHAGq@kn~xFEXdvRhd9qJYC#WNeDbF$S zB~uq!TO^%h-%(!ui0uaf5!EUiRcZ+dv49X!p5yxGgorrMHo(9!@77$_iD&M_LM?ZT< z$hGsr`!>ekQb|3O?|wyP?u<-RkCYeGk2M1jwxrUY~Lxr z>xhker-V#Ry17g4(KT&NyJc4&i`5|_)!^U>(#=etH-GL!`UZ9MAGLAs6CqubtoB&C zbk(+Ut86YNA%M`Jy`SyFwD+2?HLP^@>*zZong3KO(@Ncz`@31ufv*L~yrMGS)^8}ll)QBZ$)Ue6-@47m9$7{zw zbMwpzw=P_=rMO>Mnli9blU_W>jce34X~_`?W{jErh2}Q$oo?T~FZt_hJ^K&I<@UJ$ z$E3c_r)B#N(A`68Gc7r$Cde3zDlcoz6pSh;sq@C=R{Og<4e#x-HCfPm^SY+>gakDt fh>bpQb1=l#8B^Gr88*5;<+!eZ${N?VekMPBtm7fM%AcU^T;2fL6Uvi^hcrtqea zx-AeYL1q~@RuFPxN)I?AR_Wji15$M4tkWP^9KhNqp-&;}3?01yBG6*@jEmVDY6 zo_4~_;kL;+@*zTlEF)xOfshe0Kt4ohvhOJ1DCIhf=eYJg^%^o#LdNPXnvW0(BC-bEn_T{mzkgwU zg`rJ6b%a+>vi$%cqb%u{R0RbM0U@J%lfS+uWHbWfd)fOo4^8v@`z)N|+BpUl#elM= zPeVY!)P7!Ub8m^x0!#D!bey?&t&cR_j~$bfd*qAf8B~-N1wn+I3`3iknB|$bc;zIm zo#Mh5?q2yyv$eh<5;pV&%OQxHH%OzdI%ekNwwanRb@s)rRYb9W)x?vJ`R_qTcXWgNlNl{j zBL{4mVR)2~EH2+LefYT0$Yn!2gywFK?t4LK?v@Qdp|NR3KK8ilo%4&?;AO4hDJM*6 zi>SCT`LsHcVv_18#VExj#U#Zj#U!OzrIddEA0e?C7b@lbXaE2J07*qoM6N<$g0=E( A_W%F@ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/feed_go.png b/base/resources.pk3dir/gfx/icon16/feed_go.png new file mode 100644 index 0000000000000000000000000000000000000000..f2eed1ecf085b18d5f4f9679392fd5d9226c63a5 GIT binary patch literal 761 zcmVNYz3XHMWKZ)I$ZA9z+8kMGt~U9g5&Zh(&K+f_RX4 zs)%?{ECm;+D8`7410u4FBqL8ri3Nm+&1KHNLx_k2J)?|1$<6@|KhMH67f;j4Njqc( z2|++WbBrh6=7CqZ?J?Fa^ZARkXMlsx(l<({Lz0u_q{K?75uv_=y@Tu>WN3ofSDAm4 zvUF_jW$VeBH>v@RWQ(jIAqa@@&sjcsj`?XeR;h32zL)5}iJ2)$*0HZ=&{O3FX(uBq zNr?r7Ko!_pq5TER-)XJ=s;Y8nnMw0Z|DFQ|n}=ObHaxmD=VWKZwv<>25w(i(7pQmB z{!;$mc@GXht*A;xStwPOu3dGf2epB*_zbk?Xr*KwcJ#s53&)mg0vtj-1GZeqOi>`m*%{;`>0#nZ5pPc&ck*!nkF^1l*o}F rMT!JD!$YjA`D(r}P@rKdS#tb;x8Nj$twIaT00000NkvXXu0mjf9~xne literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/feed_key.png b/base/resources.pk3dir/gfx/icon16/feed_key.png new file mode 100644 index 0000000000000000000000000000000000000000..156bfa97196cf588f37d632622df97ebe44e33ff GIT binary patch literal 771 zcmV+e1N{7nP)$D~!L#YUl~BZHvq649ZAxf5_EO z>2z#tE(pVArP0&Yr$1tCNned9B4GVGQ*U$iJe3u4-8}O?J^S6ed`@fYlEP!hRc=p7 ziX+yts>RSFiinXcvb)T}6|TI;?H|c?^Yj_DG$=grl6G}YS7}JvP5IfwD#s5?bs&&r zoH#?ShlQV*`JB=SJ%iHw%9Q@l1O1p>RvG^^ygS^39y{hqBmzj)x}YqG}oLVMd^Qx&;Z zUDDXKFE{ML>NTkbvKHEWcbZ&*h3hK4T}scruCe-wG%c9DRM9=(abU1dXz!I2`iLYS z98y%?bHe?H$oCL4`UX^O+w)K_t#z|MZ0W6*Jo?B1u`4g8Ip%M$xi}f>FDT~ACX|iq zpoJQDiu+X`KB%^~qxk!*;q4t-Xdp%2WbLlA{{tv__{?i0Ac+6~002ovPDHLkV1g3t BZaV+~ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/feed_link.png b/base/resources.pk3dir/gfx/icon16/feed_link.png new file mode 100644 index 0000000000000000000000000000000000000000..c45a534597a9bc21d7763c6672e5ab3a7fdf2659 GIT binary patch literal 806 zcmV+>1KIqEP)e)p@r>Lu`Vf5 zW#SyQDjfx$ew|kj^TZG!BFm^}G#fNX1cZpk6@LGk5Rn8HuVdYtELhHS2e^EMYo|z? zG*Yq_b%KC^{>|+DitV59)GlTwIQ;=P&H@|WrL>MTrQRfK(jaIFFaZQp)z9II3+#>U3nY^;)ikkhxug~^8Nm4EFS z9(L^0_ne=c(?2j^?b@{_9?iLU@Sy4GXov$;llOAY$&WU&k*g6bhicdd8VQ z8-|C66^li)v$Lwzs-s7bDnCEy7ZiFIN;Hr+(K2xVoSz>JfYHnIwAu}$qoWFi0;tt$ z@@8iA#6>&a*{XW$rud^lz53@5DGr)HzuVdIY3W>Q)%qcG&JOe z?b{8k81&cpRoBL^Jc!bl^>+3f(XZTUF*)1gv)h|>FL_eOye{pWJ$HVvFq?C1=`O7( k$kMudm8qEpGY@wD4`V|Pq6VErV*mgE07*qoM6N<$f-*aKT>t<8 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/feed_magnify.png b/base/resources.pk3dir/gfx/icon16/feed_magnify.png new file mode 100644 index 0000000000000000000000000000000000000000..3023695d8c6c1e1bae579de69a9c03bae48cb968 GIT binary patch literal 737 zcmV<70v`Q|P)Wh5E$7yrg zg2#?^OdKI;5K}@R20|nTVn9MbKwYu=Tc`QMX{l7l#1XQD$vF~q|K!dhF_J_?5`;)y zGcrbdmiFmR3X%qKkZ0xr^AtN=KgZG;s%-@78i9@53_eJosE?4cyTii#dlM8xDA zuYSu5pYrHQHkbMNLsotPW=}COLzdAiDN1rueMkss3^RU^@q-+i=kjMR-7Iwfxo$ff zFwl5YYxWJtFT5@m6+KcB0e7!(_8r=Xd19X7ahJwU*(`=UJvAb2B)a!<8(W!+kAL7; z?k{f%d3w>q+v8oKznINzKvsX^gOP zk;QLpw?5HqHk4VZUz3%!!8B3UDP=`Y3S!OpVW#GQy5#CvL+ysVs1y}tzXo++cV~yP zCMN=cy>*IRVEqPJ=D^-HTYHt!eW{_r)O|w@Yj+Fvf7h&T-J>Lxqb^bL<9jq(tXv^0 zJ@v;|mNrki@z9I1T9k;(ZX~Cq9K1%eEBS#MkKBI*XX`r^Xa>XhWCbuJe`$z&$u+?!#3$#k($ zYR7OtSWq_`d@g`$Q!*K&ZitJ+5!`(XL1V(834FnW{-jyU1<<@%I!hcMIOuP83PwdK z*l+r5lmxLch5Ar*ZfG!cXl4Sq?@jccD}`>kRWP^o1)w)Y=bn%cFn5jGRP`5i>mIDv z2FzDFu0Fd+ofzKNG34TD{s_Gn3P1j6BN;?lB8iM7+R5OhhUVH){t}gE0;iXy(&+6F zVe2~Ed}_rA#R-PYEZsRSiN$aE&zM0T3!L_-$#*xTexwFS&LebIg|Kz|gm0{WzxgAP z+8bw8?LkA+?uyz}@w3IXZ=L$e>JLp?JK9_dQ16R#s!!&07-##4dm(}|53Gf@6rdFA z8GuCfNuhL&K=dI04?tQ!smiP_tF4idL}xi0;rP>1z;BVkXSJz1o%8PH0@!<3s4|Hq c@8sS41@Sp1TCQ_Hr~m)}07*qoM6N<$f@uN`6aWAK literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/film.png b/base/resources.pk3dir/gfx/icon16/film.png new file mode 100644 index 0000000000000000000000000000000000000000..b0ce7bb198a3b268bd634d2b26e9b710f3797d37 GIT binary patch literal 653 zcmV;80&@L{P)WO3(`_cf+b25@DJ#zdQm}8GzWtq2-QnZ8W6mB^kfeK5f%S{ zUW%tGMCwrwic~ZrQcG=4f?5bkV+3dRk8hw6bk~y$KX#b!y*J4EJ~>;dRASqrSu;ZpM>?P}K~6AT zWv6Dmq?v&9LdXC(m%WCO6ma_di$R(v$@ad_>@R41N3N5lSJq9@6CGhX84-$%Xrd_6 z;){?{E|Ytt5$S-&Au>t4wDlIxdkfe-a22LMj``McG};r8@{GsRPm*+8fFey6C)@ifDBXVyTw(N@Xd41b45OFg6x_QA zpwLiigyy~cVoPxW^r~C7ZQpr%>1$*HKmv~AY-qJw4;gUecS--wnqslISSS=^KA&Ic n@BK|Onfz#3R%n{$a)0j^sqv5F(1NTL00000NkvXXu0mjf3S}fX literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/film_add.png b/base/resources.pk3dir/gfx/icon16/film_add.png new file mode 100644 index 0000000000000000000000000000000000000000..40d681feba594596c64e0947b8cae5ce9086f919 GIT binary patch literal 739 zcmV<90v!E`P)GL6il?1Z7P2*|7g?{OO9$@TbH1?j^i>BB&)xBSKKI=BdzS+s=YPijNo#8> z*V5AR)9?3h9JknJv&E~ct9MK$)0#*?;BA_wANhPfI2?{62Z2#lRW+c~=~hJo0)xOm zJRVPmX1?&(C%^N7u`S*k-QpKxJ^Z(|9^Pm)X0%%ELPbRdL;|nZyG-C)6h(2$>2CPu zHV}LVG)@CAV;R;g61NZ@w6lP;HQ#_4pj`q>&t7&BZ`>!@b{&p2>% z;uFft%U6_2<&0b|Pl^NtP7rvQyz7!PR)fwp2bz|(sCys8g|R5kjl@7;mcYXji6kKs z)YjH=1P+m;7l+bqc)r<%r<)y!q^=_J`7#F6mmrhL*y7^iP(eWfClc80_O#V%Wl0vt zwop`5#OLSdv$?ssX_0`yoW)`Zk)#&_^V?|u0JO~k^enKn{t&OHI?)`q?>5}4fxY|e zuBk)XbwFS?n-d0uVVESnbhw2(ueuR>LE$YI0sECfc%li8@ENF@PxkK%^m=`=va)i9 zBrR&;%I)(Q{dgav@drZx=%4f;JlQA+e(wti%o3O;Nv|Gm!E!^6DEAou9&c76g5d9W zURG8Hg+eh;lK%B18OT0MwP%M?*Rq2fby;=r6z($h=w)1caPPQFyo1ux(o9K72}LBL z^bM2>7yD0RfN}3VS(t_E0~tuA()Gf^!c1OX-ojCTB3az0XgskiY+KQ=H}?tm{{Txk VbfZtx1EK%`002ovPDHLkV1hC*Sxo={ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/film_delete.png b/base/resources.pk3dir/gfx/icon16/film_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..23a2508c5cb8bdba45e6472961b91d29efae0f42 GIT binary patch literal 730 zcmV<00ww*4P)LxFQii)DB zo36qj!ATU1Fr*8$5YuuNd_J?HeSTut3w2Y&E!&h!7B=Q$6DS(b(Wx$L<^ zG#dS2nx>EV-rn9GC{!E{hX-|C4@fCTJ3BkKFB4F(!Z3`-#K}k`Qm`!wXK5q$t?Gb+ z4&o5mbx%{9EV4Nuqy=FDr#v^Yr5I>D*JGz}J+UK~v*ivH93XBJ!@cTVp5n9I=5%w5 zyLkdN+{Guk5aJW@kmz640R>BldP2I?KEzY+P^a90&8S3I@*w(Wsv*P)NpC+wxC#k$ zB0&$Uy$)b^X)$I*GZxY{NX~{ZJnzZQZxY!W?9LT#B@~m_{|d;ik-$$VZ!_0Ws~v~KDE}>)eEA-mz6>LD=A!2C zS7C7=rVhrtuXOKKQ?@*TO85!(XA5UBqkp8%fW=oaRMa0v(dXA-kB-7Q`V3{hQpIA{ z`TP-PiKoQrm0KuDj-hD1AJ`xL_YYj!0L5fw`6C1=e2ggD87JaXVPL z?*-O8Z$@Tu5^1WRpHpBc7|$0_R==ld+Jjij)Uxj{*iNkLiNjaQVOLblPfLtVF~fp& zi{*ajU@$mDf^uSDWMrgnk literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/film_edit.png b/base/resources.pk3dir/gfx/icon16/film_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..af66b73f2097d34f01d86c6a4a4d7f1980f94dd8 GIT binary patch literal 855 zcmV-d1E~CoP)l$D+s&Mu=$; z6r}`(5yA|KE~bWoW;aJ}R+>6%H+7ruIos)3N#vy$exDxx|L1+4|NC;~<>l`pkw_}x zs;sOuW0q4~T>L>4MYAMHj>g8ujDKq?5~hd4;oHRF($Z3SHUknzsUQlb*Hk2oA-0pd zm~^N@idDpbNitXjIFfW73$#Gl$yODK*Abc14HP7NOH>i|*Zd7(T<{4BjX{tFgWyEA zpc94!#@J`#7ST211|&=%))A79@5GDo4lGw*g(7T$&Akm>UMmh{s`e*ofS6s+}$NBwN{M(cm^&sus=E*n>5JUWHdv~ zX&}Lbaoq@zat9Gk#7)MqCqEFkck{OSf*}t&(-L@{7JO=|y&N@2AhsHf#vI$3fmt$8 zU}Z)yWBY@gIqQU8ON|p-^%LGb63`k+fMLTI203SI>Br@{5K zZIq1$3YVUG()oKpy1tL7C-`UzMf7saVi|VKd5+|)Enq{nP^x82_*2o}+!~RBf$YVn z+dKZoNS$*?yqic{Z%CDu-QSU`+Q3O%G6uV^L7%Kf$h`nxn_EI96gu?j z&qES>{}`s6JjBIWFwoIGcD~;E<$k-XlK#xk=?0uEPyK);Yv%@+E;6cCWSAiH6R(1< hk%NVo-a7D~^9#54wyk$25e)zU002ovPDHLkV1gTsf-L|5 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/film_error.png b/base/resources.pk3dir/gfx/icon16/film_error.png new file mode 100644 index 0000000000000000000000000000000000000000..88f3d69bcaa67e9674375232e16f385ff7370776 GIT binary patch literal 800 zcmV+*1K<3KP)4(U?CVpBcg61u#2F`i-AOS z6QvhHNLC1TSx})FYT3sYZjgqW&d*JEK6^$g!|lM27vA^%|ITyH^S+GV@BgYONDo6x~8MxPFa?p66bwBpPETP;UsND-NrQ?1@%M&*+qL( zn`F@FAxJ6&1-M{u$M$UC?Bx$S3Re=v8wDB)4ioo@U?2OCi*fUu#%SYI&c=n|<}BO< zCkVnX;xRFlRsjXgL?t0v*g?FDeL}hR9yGE8z0u8xe!oH__wZ=~niN(AdusV2WHClaC`8Qi7ueDPg%J_)Y_c{U zwpaV_j4Wjmn2Do2&zJUI9Z&0kp4FhKHYabFr;#~PJ-L`kut0Q&!(qvBv%8F=E{HN9 zP(zz+4`7Q$U@(?2=FNLi<*^vQcO9#6HoWLx?*jeVETWLmeoWlPf;Ix$z61VyS2TW@f zloF?jf`hhv)yWm86()~*Xy!Mpc^)Y7VahI}%?zsk|}Qna-_RO@suqG?RMAG|+MmOpXj9_^S0eqpIl_@crGgX;oH?s-jZ)N($=w eh~%iM1OEW6IIf4)XAG_Y0000s+KnkY`Eo6h&V=bWA+7NR@wyLq4U|DET3pYsaU)z#lsRm~+9=1NbpotRP@QR?BSgMY-(!CUtKd&Fi%mGr^Lm|%1SMffWkU;#IdzCBL&UGNwUk% z3w3;hXa?gNmU=Q(-80<)DkYZ9q5-ko%lN?eIUdbj+ zNQ|)`L?h9?t^*3D5`Kc)lD^?%tP?)NJ&4LSybYf~_iP~;JICqkrwCgjflLIcSm-hX zC7Z06WmSkScoB}2V{qQ7?_VYKcURCGd(G=TlEDO~ z(CBCi0p}ZRwi-}gR@J|x$~&{u^2NTfu7%?dax5>aMwTT;I$0A5atT96>=BBk3YfJF zh@+)=F+%g#I1b!O-j!j`Lw@>R%*SKs{{1;xde?4ixgL({f}|CJkYXH0d-x8DlCQz4 zG8`#53q@0*s0vhQ7>|siFmpemY*G9g`VjHn7VY{LBE)mzioa$e3H2M{(9cMCAqXOR#lX@1Tgnr->YYTBeqS6v!3>T6kRG3WqCo3x$(B3 zLi6Ce2?`$`uhseluh-j80yoh!G&JN(G)7612HZE7ww8Df;r(Fq7~K;+Jh1#9Xj;Mx rxbAV+2r)%9SQb^qJz1*-|E>Q8ss6iyye%@B00000NkvXXu0mjfIy`F+ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/film_key.png b/base/resources.pk3dir/gfx/icon16/film_key.png new file mode 100644 index 0000000000000000000000000000000000000000..58921624ea7ad94f49d7503917298b534f9dba65 GIT binary patch literal 835 zcmV-J1HAl+P)!JGa#`+3sF6FCXg_P*h=nl zVSS5|%jbY8I+zCREckVFm@dO7|=`h%V0s3!wCy#g@Q7qq;a6=GBi#`J7dsP z`Ca`gZvDuOsu!8@kEiD~^tBrXTun{Q2#KQ(hhuRp7Ry!wdV71n`Io4%#>VO*$ywObA>YN&Z~)`FsN&kB7Njt}b2I@tY5~s-I=Xj_awxP5R^J z3U#HsK<9aW=? N002ovPDHLkV1n_Ef++w1 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/film_link.png b/base/resources.pk3dir/gfx/icon16/film_link.png new file mode 100644 index 0000000000000000000000000000000000000000..0f24e86e4028717876f6650558d2451ec644bd4e GIT binary patch literal 830 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 D3;i%v literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/flag_pink.png b/base/resources.pk3dir/gfx/icon16/flag_pink.png new file mode 100644 index 0000000000000000000000000000000000000000..5f15e526c0a3244f5dca94d7d6f0eb8f28e99c7c GIT binary patch literal 651 zcmV;60(AX}P)d+j7)2IFP!RM|;6qPprtQl^u+-aqSi}MFlnvfmsk?R-o-Gupj{b7%)rcR2bHge)vq!@bbYa3An=n z<*|lTk-eWn&pM#_2J}#jh5#E?Hqhx1em|E7pr|gu(nJS3ZXcC^EDmV1+m9pV!$%HW z@&OeT^{bRbZCeSMpit4>t>x{(+5)(Ts-WgpT|2$oPW9&jRr7pUO!00L?qAWVA3t`b!EDVfFf(juaajm2ewGR{_!ijCMa-%ku z>$op!<~*r02llbqYHiJS(kyd+tkv+ibN;>WSsXOT3wQD7h4Y^0$MYPXQv{%>ko@_!-JTr^1YfBMxRMTQ8AJL!*9Aeer6K*nRJ;@dF@_iub z17@P6i(vxv1F@bA`kEO6Us?`4JQ! z+XpBxssP=ppWO*3a76=;vz89E!L&k7RBB#s#=4x|`{;RWi+t!IE^*bqWO#wVi zZaDrJ`239IDQR~A@SPN4Q)MLfe0(Ho6*XLA>R!qE%?Pz?(Q&$j0%Z!&arDJqo0|XS zU@}q{la?&y6AStZF0gbbNC9Iwvjvd{hnLO2;v)S6++;8BDhT)x)T;{uW2MxECPn{*ELdZ1op0xyVpxzDdhz3h^YVPo^S(T97!Wp}{CC5s zOO0&MCbYN{*S_u5sKy(UFm7-Lr)M|odnZ1F`|tp z;QLC~;7ZS9V!0QqC_yL9nVW1CJTMZN4M(R$+ zOTZBsFr_4h`&3JNv0I_O8fwI~`z}0v3|$@I8UFpf@&;uE8s7DoF&~bRfJhmzX*a6< zs}(O~Kx~cpZxH}pS*S{qZRPWYW?G`zW8AQcn3#1@S*BcNV6f!zir{5lPjYZSt>eR~E27PJ0+es0y~s0ch&nN;M*NkCc% zXiQ#beHkC&om4IpK8qPut?)aNVjs<%39&#|d3=N1!OZi|I!ONj#Vr@M%?lVEC`+Fg zAQwL{?FfzVoB-$9WC=Ju7r^r86-w*!nR~wgLM67#gs;7-00000NkvXXu0mjfgI^=` literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/flag_yellow.png b/base/resources.pk3dir/gfx/icon16/flag_yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..14c89a5430dd9e34b445564c972634474d0aebf9 GIT binary patch literal 671 zcmV;Q0$}}#P)h~F3KnqFOq_yZYrcmh=dA~yr_$e+EQlLNOGM%Ml;i# zU7Vw6Zfq9mSh}^jHcU1p^JCLZD)&8iwzFjZJLh0y1$p5v{=642&yVMMd0qklkxl-4 z(M8=Y*1b6uGPP|>4YuT`RLb%n4=(L%zJGQLxM;W>UlFiB6XECJF0cUu7*7+ty}2;F z$iZSFgb#K51w;U7TAHJ!%Yznj4XknkpGg9?Cj=tncaV(Pu*kZQi0HutwHVN~Vz#dy z?bmnnK*b+mb6>}?_`=jZ#9R*%o32OVJB?(ZAJO?1uu&s|o*D$)H=w90g!f}38ZYGW zz$O8p=(;nXx{H4CfX`SUBs_Xqz?h(#i-rRvaF3io=dD6abXW1kNIxP?iIpSj?Wx$b z3_jBy_|1Dc;0l--67ewKMJxQCo0xJ+mkbSu;p!Ft4Rlf0oS|{aQrJ-ezvUp8Lx_x3 zf|*qy86QQ=Pa*1S#uu{;V{K(HlSg^LnFh2}S$JV`x&48y2sa2SQ(^A?I@lE=Sas)EyF>d_)lVCHYIEUy zbsEa6J9wZZ4XE4CdrjneSRacpBp1O#uEo2il0@cCa0R6=D|ZSVWX`|hBK-r%dTNTZ z0=`-mC$j>CVtvDr^a`&E=)8S^2dY;CJYW8W{JA0X?l;dl(LPG4VetR}002ovPDHLk FV1l@oDiix(K@^6+>g^d@v4;gkbWsEoXE%32*i1tcpTNXd5CcIl)ECgqz|2rE6EW}s7R?kl za1q`0GCkMruC6-2LANtwVlsgzsp4?{@7$`KBv!G66>Vie3h?3OmEEkjwdLG0PgLVi z`!N((f$A@n17Ldj#`};0I3@iHJ5M{#IZz|UIYRm4(!uV7eYIYIwQf&}_2J~}>pQ^n z6o8--^T(=hkBNQ_k{-_GWE;FMW7!p}f{NG3nHZ{D5<3d8&tLh%a4AqqnjMkr3m&fkMdECD3N5}Unig5wy40;>lo4j~k+e}v)` zR6)J8Mk*u=SpB`p6o)7j?S0T@9?bz#m@l>gc*zk__|*!FMcHwP!gwLJvS~9c0px8E zWg@#5J*h%>dq^uaFBvVQ$3&c*y#>&P@VnG_z zkezqQ&je1b~~$O}L9 zo^;|X_f#3CS5n-cFHBf|3c+u^PpWoka6G0Rsr|AOXUJ zbHD{5nUGu>5YB96PUmjGgM{$-j5TbT8bBGbz2R zHjvpHkWu0*cCs9&;{|Ugi`d3|T+)Vj%kXX`qqQ>4W)|B!_mMlW`2x#YyU0W#8Pyvn z-<;pE4zUG8k-yYxmFW4%eIAbtF|hR_$8YW;YMMc&ZY1$9z5S(QZA)e!-q6)Y`+^>Z zzdYprlOaC7jZYg%{Ey!L(s5u9Pz1(+vk%UU4EzNDb1nO~@as(g0000WdP)hGNhxyAUiWDzvzAp&MOTEEMdb z-KY>(MO>5!t%8VV7Yo%QYGN8YNyf}*Cds_{bMJfa-s57@1`%R=;N!qq{J!tNIfw}V zSC>!nb?#@X*H7?^&ws3+j;XJ@K4fRgr*T&=dxA;QrFmAo*X`tIwBNtPka>1QBzs=m z{g0)1*_R&2(GuTpzQa)xj3mu(+O)`;Va<)v(SK@8z+Ic0Zlmda4xjavYPGDY5 zFf%&E-w*RNuZ&sW32iN4H3Sv-bCerFjl4%J8W&=wzo+`*5{ckf*7fdTVFFB8ACmlrB(d?gOB#nOp>jh}F32Bg8Hs zHo)l@AP#XFT#cr*Cf(hD*f!GL1B^eu#=Y0Fn7|<7VqEkJi5Kb+XFy^QgSaYUE4Vm7 zYye8VbvHhth{7Uq5sByPvI|SFI6!O(u@%H=oXG;{e*qG@xwtyp6qQpMT*ebgg3Exk zBh~;R;?=wIELLlg(3vHGHsAjBk| literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/folder_brick.png b/base/resources.pk3dir/gfx/icon16/folder_brick.png new file mode 100644 index 0000000000000000000000000000000000000000..5dea9769a2c160625e9858f79e3ae16006df4a08 GIT binary patch literal 735 zcmV<50wDc~P)X=_7qeB4SLW3qiVT!56v^ahZ*4{{+FMqC1zm7hMQ0y6_JWp?^RP z)}pkQwqUW9(#A)lX)>AV%w+C4E}~V7^#_Lo7w+e9?lr2)zf!B!ysfRRVh{wQBj`uX7Aw8)BgFv&O-ky7BrtfQQkXqB>oLV@q_ip*Uq9`#gONJQNYY5h)(}H`T@yzctU-I Raqs{D002ovPDHLkV1j*fRJs5F literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/folder_bug.png b/base/resources.pk3dir/gfx/icon16/folder_bug.png new file mode 100644 index 0000000000000000000000000000000000000000..4f791b684b7b97da5d64472b33d5820f762abdf1 GIT binary patch literal 829 zcmV-D1H$}?P)_96=|(GO{L8?@n2w;q7vUL+;Fb_ma5X+-J+XMx7AJc51J)}zACp) z%^6jl5wPj|7Z%1!Udmz84g)tm_X&z4LmRChyo@%_A)3v(n%e49GdfuRb({LGe>e`S-g&F#K>GgZ z@7yWn=_};uY}~;|XFsLxhGc#|n;kMYzg>H|c3xAHG1F%H{E|6zz1KSQ>|T;#fqpwj z@8~@`m$p-F319y93x5@cnC~Xvwu~kk8#+!^8)HBLlm=s{zrKb{Y7v))2e>v?VDGXm zT)KCGl~1)(E;!V>W`&6SVG*f^1hf2+kBNgSNX)~S6t6zLoo_Dp;FySQ>6QGM`<1ns zS9tI96TIHEVC4NHcdr7*A~Xq=fHfN$x)l@PWTSBrjmxNbh@S=U{sm|t6Ol7MJ1o_tkW@mo8YBg}5RH8x zKoga05;3vosRrUt13druz{%auqr8YA#iK$2b1^{lv#HYG;1s0PmeerU00000NkvXX Hu0mjf;2(pv literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/folder_camera.png b/base/resources.pk3dir/gfx/icon16/folder_camera.png new file mode 100644 index 0000000000000000000000000000000000000000..c9519416dd4c314413210b2cf30d803e0be7b4f0 GIT binary patch literal 729 zcmV;~0w(>5P)9iwQ23rWgy{SU?|b1z@kNMgD|5I z+C&Q%F0?XIQ!9zYvT|nLd-uKj?)|p#M`Y2aFB}e>#o=%`UnL^^&-uHB!NI{H;L5hK zi0r@^!|?F1>hJFttu>>gqe|^gFfcG6y}i9GEG$r|R2Ul@xrU><>lpfesbOYjhPJjgYHMrh?(XKzmo}{m@jUWhESy>^U&l3bevp@g1 zW4fyL=uxFS0E)$9w6?bL=tDhE-+MrglMRiuA3n^)!~|VkUChnR(b(9CF(&6L@s2c| zxSLfP>8tAq)-W zav6~t!~>O4h^JUvTO$m^zZe+hiA%6a4spWz`Z}u%lU%Etrb*_1>*rh#zx%1cYGg(X$qqQbU60+GW`RY9+;};3T5MvBJ#=|ch zV1MUT_IElCMiEsx!}x;{#Kr(<9bi+9wVLeS3$z1MQ&RxrK1M{W#)U5tyMY(JB@x5v z6Z;USQA%*eA=V<+P-y94@%9a7XJ^&s5@SSMiZfr3bOV%+*a}Dr5+mXvHo&E2#Fjy+ zT~kg(6c$OpA?c4z*bOAz*y1u`ONb2+r*ZK|0KH=%iTj?0>(!=`E8>ctNETcXWZzZ? z3F2+C@+?+sk;KKn40JrSbgTC`LJx}KKVMG(^&-K^y=_VT?>qklwf%D)EyQ}q00000 LNkvXXu0mjfDN{)R literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/folder_database.png b/base/resources.pk3dir/gfx/icon16/folder_database.png new file mode 100644 index 0000000000000000000000000000000000000000..5193e2eff36d6624e9712baebb81da20959056bc GIT binary patch literal 687 zcmV;g0#N;lP)l`516uN0Cy%QCn*#P zN4+?XnV6U$gm4+)tOVYBPqW#iR4O4NG#U+RwHhG=0M1IFaU5fYPBd9i&QF= zBOt%>{_2-vWqR6}e=Q|zuYC{Uu?29>0nqF9j!t;*`+!k9HF4uzWQ+mrU&a`G`uoz? z#gBS;ID~+64r9zo0Iw1eXI_!I(0|i?-!<9Z@v?#tyr}>L)YYlM;xxzWB zci)1-?#>Q-`)#}rhzPl%F?4Yb=iJRf0!x1A0_U$k1q4)4Y2){ok#wD5&4{9uo~C&1 zQXYT84`6>h%AjLt$N-1h{%&j_q^YWt>=;P1=igr4zlL%fL;19?jRI!bA-Ztb`U~VH VYY-ljn{ogE002ovPDHLkV1lweE*Ss- literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/folder_delete.png b/base/resources.pk3dir/gfx/icon16/folder_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..112b01638e6f3b5995ff11a07c7ef9e3e50b2780 GIT binary patch literal 666 zcmV;L0%iS)P)#NXU(rVJZ0_Z7&gXp3z2_(q;VkBGMmsaW16Y~9 zp7fgr29!F<6RP>ub)&O4fa*V43V`C3yGz;wP~!A;4tPPFm}sl;XZ|Jd$pb)31sm2?QX#5xu zDMxIG3FC+rZ21>aF->7BLCkLhiNJ=4Xh0M6jm8n%ee?z>@vSZsmO#QHQGTDG?-71; z|3Slt3Z$mMI}gV3jscN_SKq?<{>Mjwg2jd#=*TQ%RKcRuE)beKot?IvC(#|lF1=DdvMQ?PApSc z(OerDrLOlX<;5AkFU)$g!?9p2(@mCY5j}K^A z`%F()Gos|V2Oy!%=+bUOREP)Iz!8ao4L~j+rb@K)1;4cy?z}jjz=<|ot9ojHO7-2^ z`+I{3!zhCP=C$6fDzWuJ*>mjD0&07*qoM6N<$f)0Et AfB*mh literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/folder_edit.png b/base/resources.pk3dir/gfx/icon16/folder_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..ad669cc7814eb52a0990c156e4358bd8d523089c GIT binary patch literal 733 zcmV<30wVp1P)Ln`3m6cBjUs{~SZF1Q|l+PQ4$F&BPWU{LQ5Rm}%Yp+9Uy#II9~vucwq!AZ0U3VS=&d(VjEIGJ6F` zxEYZ+Do*Dgo&xS90WcC^bwyaXLaY<13Xc{ys@jsg}$ z5G+=Y;0}5=7O5P92480MbaXQ7%}6B`AYHKOFX}h+}d5}LKg{F2q&8;J?*AuZJvty1~9)ANwocD zyswqfv|ByYH|QiPmSI$m{Oe0B$hidL4Saj?irNjUNTgedgFr;v@FyS$FAiPZ+kvpX z-^tbQJARF~w@xzf^f?uc>#?PNS(q}q__!blpq^>0+$ab5#~RNbYmZJJIiAFc>3MLM zPag)Sv-P!|JI?j?{%Z?=0rqdL^*1#yN_MoZL{i~%zgRlF`+VQf|HkwKvQRq#2{xLW P00000NkvXXu0mjfz!^#T literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/folder_error.png b/base/resources.pk3dir/gfx/icon16/folder_error.png new file mode 100644 index 0000000000000000000000000000000000000000..1af8809513d4c9d70db4b7b91b28ccc8e960fd7c GIT binary patch literal 727 zcmV;|0x127P)k#I6Z`-y*Ux@M08f%%l`nO z@l-64O`xJk`4{0rj^gBNYW$6$A&5oQ0giObg#;?wmNmerFRqL&f!YPa!aV7gQ~33* zfT5J{XKv&rjcsR%B~qAp1|l#14-k69lZ|9rPcN;iD1z8A!apyV{{Def^AYlcmq^zM z{^pAiC{+MejVefK5RK;0sDQdzB%ERX_b_W4yQtl`hv6@eNyHcMHGr_%2LY<$kZ=mI zQ;5wWHis>aF*}hXy&*$1-$TQ$)67hSNE9p|b`fAz4H4@8pl%us^QfCAA3&5LZg$f(DBDB;xHPT~|VaAD}{1e9QKZbBw*~ zMXcCm4YU$mAHIFO9iJnQ!&w5gNgG!mb-C4wrL6ZgL^9&m+c z>c7)*W<%?-n@u~DM8!T-E$^RwWp8&YCbk}uhk1AJ(xi%Xt_bM6v43>;$w!-F-cQuc zP~~L6BbLmP`#iu<@71UAl|IY`*6+XDT~<+4q$+i}B7&+m{RPs0S{LgvUQz%6002ov JPDHLkV1mJ{Oh^C# literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/folder_explore.png b/base/resources.pk3dir/gfx/icon16/folder_explore.png new file mode 100644 index 0000000000000000000000000000000000000000..0ba939184d5e2257e380004ed799f00f66a49277 GIT binary patch literal 679 zcmV;Y0$BZtP)|B!lwB?F)%&66ocFx{jBe!85I&EQ#75Y65B5(Mx_0d{Cg3j-*JeIvt~v(9 ztY`S8F>>s+V~sTmN;}4H=Z!HS)(DKjt$rUaPhR;f5G}c|OUlyu`rOm=z&+MjoL2Ek zTm0^)e6oN~%J`&=(gmjK2N~YhK_xcK zEoV5BWBb;K=H{^+EtW(wWXLTdS4FOhvL)n}sIMf1VICJdydZX>U~@QG{;*1X#WjC) zr1dbuM}d?FAAx%5Xv>qN8EFR2i(h1**=X>G)oOfg_U7?X#32k3>qH~N`C9QvE@}^n zGhqY6++vD;yw#&i6Q>Sed3?u6;$N;m{5aHRIk}}XyzB+bjo7>Llo{{)Y8o@oYqL`? z&lySlkNcO8o-Otluk{V>>wfd%Vbe(Bf8CuZo#-Fld&_&*ZX~f0KLJ#yHcZ$RnzjG{ N002ovPDHLkV1gJ z|Dc7=n2G635A>de;xc@E0j2M7@H(t5!rCkp!6?yvUBi##N-2;Uj8ZU_h2kts&Oq;J zIC=x#-G;d=3|@e@3y=pxC{>(o@>d=Z*%;^yN~LK5XljM_0a%;>=V0Ixe7FyNry#Yr z=72zHahAv?5GUB&EZ*`Lf_OJ>I*aHrB-nttEU{D@QY~O!U8H-@dGIg>CCx6}zq1} z;{+Te_dkL{0bV{?a)uE@AR>2Fx75VHCIjaZip zz4c^JPNZ>ZEfNQp2HA;3K41}DyOoZJ{IZC3{+2-1AN~69++l>1DANDjT>;dj#mUp( Zp8hoRQY~32;;v|2 z6e-B2B zCE(hxS3dK-rRD4TH?wNZx>((BtjuOJ_pgyBGdA>1yDCbtXz88 ZdJfaffI=X}!C?RZ002ovPDHLkV1kN7cwztm literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/folder_go.png b/base/resources.pk3dir/gfx/icon16/folder_go.png new file mode 100644 index 0000000000000000000000000000000000000000..34a736f70261338c9bca98c38b78193740fa83a0 GIT binary patch literal 694 zcmV;n0!jUeP)N@Zw27r|iugjyK_i?%mf=ZN1k*q&Uedp~2B7g_+fS`hk+Nr1A{hI)z0`VHB6Nndl zX$Di6C%-U4JXr@~z-vS-U`e(1B@n-FV+JTmdRsylL39C=TOrljOR~Cct>JYCvg#mK z1ulqf0!%<`#~!NMu5Ba=9u&fmP-Zhc6E?!yaAE01t20W#1|(JmqlC- zu^GHsMqCzbhR}vI*0gbTWQ<2wA~0LlNQ8*Dc(aJuEaI~Cy?zX0(B7i0rEb>&+G>xJ z3k&o-xX8WohAjXsqHu`)jo1ugGgz-V-_eT`kMj#kXL{&TC&D=t zDS)urCatsVt!&16hZE0Sc81**wR}pC@@4w{a?#MB{`E|khgw{yHQH-JtJz=E5u9kb zz}Ukc-s|q!`(``1y|H=m(r1&lJyin$Xxq0vwCmG)?a3aY8mvDz{qFmxE%s(BuO5DJ zao=8%%g&`=etrMina`JM0D#h8Jll;L2^RBAyP%^_Ir7+%R=MGUyuLc0fTceq_VSCIxlQXj!^EtWD%$RJW zX!AVkD?c8*u(*8SKuQ%@sC2qF_E=cn!Sx&DIVH#~lNqxqs}H+#{({Zn-5=@{)nku5 zf3}-aBFOu1S^wxm_pI)=v}cv8*Vq`5TY6m%JnGJ+i+=z5+uz2M$%)!Lrb^SB-TFjs zI#kR0$JPvgy5YYwXYD@xvV|(KJ<;r3^2e!42m{A`)tOG6Dc~%w|7dJ^j)lfdl{m00<<522?CW@PXKACkTpQB_fKD)<(q6!a}sL(AX*3`zS0F zw6d`gQ6nNMK~Z8t%sab#@63NJ?$yLsPBCXV|NLj>KQK-b|H7&B_YQ%s0xN|BLAfl% zK+1oi+h>k$?dokba4tnaZVoGI#E^0B%H#h38c1|CdK&a!zQu;VzF&Ic9iQI5;=<{E zOk$B2fcGhV>({Ym=PnYT;FAj8dn$>?49pfWFbM-XI%?E9m%txc2@y@C?;dP_QCqrs zvvdCUvJMaop1&SuR6~Utiv&Ku`O2}q5X?xO{KmC=Zd9CGkhF8ehj);`CslmXQ3g;_ zrG|hIjFg}jmUXm;2Z&h$eksn?3DH0>GBo(tcq2oDp#9|0NXea-WyGwCOjz?1`Rq5& zZX2Qb>=8GQ7%)_3U|1H(c2}F=Izu#4oN5-DWOJZwmVA1O`o?2a8>?8cdKu2SVl1iP zq|WCjCz6WKVvL$h$vtUjFUvNa1PmmEu_XV<`@sjqFpI?*6lRb$srDY{%ZD*8-Mv39 zIGmD8iY;vJC5n?MPNOhEx5ioCJqcl=)TdCKrE^V6r8aC2uN`dwq_mMNVEHHtlf~gM zQSQf4m@1nK11UgzKG2j*azqrqmyP9(zs#oRo2^xh85S5Qv+*!D)|Jmx>sZ}O6|g#} z2gNp!Az!fbk=SZUnYHH)TJ4J;uOHlj*oULO*xx{adzxXo{Zsk@(!pF(RdX`D00000 LNkvXXu0mjftamTb literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/folder_key.png b/base/resources.pk3dir/gfx/icon16/folder_key.png new file mode 100644 index 0000000000000000000000000000000000000000..fb9b4c2bbc2c94a4f777e5c3d953dea265f7b846 GIT binary patch literal 720 zcmV;>0x$iEP)Q5eU6=iGPZUQ_QKgBcNt&>&x>Nl_%pLP-{EP)t*^8f(^47Ru^ckc9;ncG5Hn z$wpF4h8c|SG30W;@4WAM&pD699qz1jPo2)`>HL4s|2+Mbh|tP9Dmzt|fpo_ES>$xI?G%C|#pH zn}?`QbvjO|i96e#XR_G*pNXHuZEC>1g@^^m2zk1LbU5d@t~JhF6b7+`hZK{t7K-?yV@KHLV-Bua}n zIMa@JjjMfT=Er@!`GHDJkxF+n{-BQP>|t@&D5Olg4rKYi0iz`2?F^<4VrnFnGGXrt zy0)$bpl!h*TLzl5QNet0I%onCO)#&A`Rn=t4F%tdx$F`wuIO+;;LkporSoW zoq$9{T!gQWHXgeQVvG2sfVdLa;%vQ)xEe?d$()Q3BjPPS`Pt~?N{B7a-V3vx%l`l( z7UH=8BcgDK{XHuzHf_5SVk=Ftj~d^!a{yv|!Pb9uB-Qp1A8L^{@FB<|#KnL?bmLUo z;i5>y__zs(;tTIDAL>Kciz57QrUg)s4PLJQE&Txw*NhpH^5>@j0000@MUe#( zhB3noqr8rL=gzt3o^$T+_gLKVGSl!Zzde1v-@eZys>*CLbp3cx>})$+C}a+0vUa(; zuwcV+YbPt!dL_CU);O`^z@_&x8(`$t=}cRPf4N=GyxD zM7%!<;-;UA>YyV;ukYgOS;P-;jT&Ai#gq+xelxcE1taS9c5OWuhzKZvGWqrn(d)|; z*X9Ktw2Ufd(- zSc~Tru{k7FvWquRAB?Cx?Ekpz=)En5w3Xd83sde7sJ?tMy_A8OEe){Z=%X@#!FfKO zPwm|x$@m9cTxb5KeRQnbk04ZQio?gb2F?ZK3nf1F@A!=}G(qrLuSvntR6siqXN@Md(3YB z1Q!9`v^tHZE^EUI$Rb1p@KN8JdR-7aKtKgB*r+xG5XX0i&+OcSw)XxzzjmB^@Jsp$ Xg^DuH;4UY{00000NkvXXu0mjf{%TnI literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/folder_link.png b/base/resources.pk3dir/gfx/icon16/folder_link.png new file mode 100644 index 0000000000000000000000000000000000000000..b9b75f6c398044761b2e211639a3b3ea5dffda06 GIT binary patch literal 785 zcmV+s1Md8ZP)aL6K`V-vR#JLK(X*jEKVNlbHxH0QOXN4CTjfvGt40I|M#Ku+)Yiq8d z;L28c;TGg(*&-*FfRgVFU3!q0bKn5y+w&YMOEeLrM3go2};w-m?^(jqeZAz2= zL*$E|+nBzw5`1~&d{HnejR`pp>Gc7meprxN9t68G0wK!~R}w-lLD(()XLo=+p9zi1 z=86KRES~3g$*>K{#fON0>%{i-Rcw831>-k@nY{~UrUN@)b%g6=XPXGQk0pwNVJV+w zqhRK2*zxsX)1w8u`H8F=|Ghf>#)>;2#|sV1xT0X_I4_<*pC+(CE+r1;*Z|TI8@M$i z*d-lO3zv}$G$5CpN9eh9kKmasBji}*;vbP^#=-v_K_>cy4EBLtz6Ex%6{+9_B)^|S z!hagM#0)}%dj*eV={z3?zdeTC)u(vt>V&z^2#3Rg-flhS-!~vKtwevfR?M0Edok2? zHY=CQ4-^D8DJSp@k{b>@wzk4zu^<|aA{-9Gfx%$lO768pBDvDi(!x+d zeSQ6SO-&82P$*DWS0_Sanxi!;puHu6!{kw^RP$!DnQ=Ou+itfTcDo&IZEa|8Zx>^l zqcz$?drJi6<>mXTtE;POYipO9nwpXtjfNv+)M|Aj;S`DEG)HT+hxYyg@Y?10VPWjL P00000NkvXXu0mjfBPD6B literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/folder_magnify.png b/base/resources.pk3dir/gfx/icon16/folder_magnify.png new file mode 100644 index 0000000000000000000000000000000000000000..0a3e7985c183ffe1e5547ae02e56c2f160a9f3c0 GIT binary patch literal 686 zcmV;f0#W^mP)D5KR;Vfzpb!Z%f>egXcc4dbT1v5p6tGa?~4~cr@F?*lxpV^g36B#KYBzmnZT=P ztU#cJlp8~0$(9F7oRNX)Cvl||NCS*gXn$uoxwwWOL_|iRZDU%Zz_0slQ_$jLLxRmY zYQN^Gtv{u{{(_hrr|*biyHKPvp-87(y3%oSyAf`6gSqQdvkem?<%kV2VFIy&t*;YR z^XwItnC$Lnb@LeS)+TUb3F<+F@;111vPk~infZG&LxGEul+|^@8c0|rs+7r$%#!LE zr5D8z0$30Mgs&^xY<*ag!SRckT)wd25;?dXeRPlB*e?_;Hrzy)UL(dsw1?<2V)huH zyi4xws{Xj*>4;d`B@z+iV{2a;#ioMj5;iI##sghy=F5nwf&>hoN|`HnUZxu!1c+FT zjea*e84uB==DyhMT;3-T(Gavh~9-=EPu=N`}Ih&YW^IR@kVBB2dh1b*<~=i`|vgv%&02Yx*P)SD11&;F(U0?j>H Ur1R|wc>n+a07*qoM6N<$g6sr4fB*mh literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/folder_page.png b/base/resources.pk3dir/gfx/icon16/folder_page.png new file mode 100644 index 0000000000000000000000000000000000000000..1ef6e11438f3226f88bdc457f55d677d1f2f8409 GIT binary patch literal 688 zcmV;h0#E&kP)CVGc zN?Hxg{(SJp>2>GN9JetoZ(aZH;Ije%0FdZ{S!LRVX%}YG;=d8L^N!mJkCd*SBx($jgG)S}+Le)f;q=GIn30YFNh3ZW|nh}2rL)`=3ju9K*d z<&~Gte>sT=5|RjR+}A(|O&3gS5t&*G5h0Um$c5IgEgxJl_8nzY#B+YU^|Fhvzo-^U z6fNn3(lBMcl9{Silx)4RpURdFw}1BZ?>}8S&h8fk5`hjKW@sP$LJL*otPOMf+jp$? zcC^*PiL>vkTOZln=wuc^%A^$j`TU&aa3ETVYE{(r=bgN835`stIePGw{uwD`7K9Y) z=4)VDHnkl3YL%JeLce6>Uubzae&kQ4(g>C+WwLc_Qfq*FlK?}j&#@fb05W&WX zs7RER>}K7~?sqveuf<-nYKRA3hB+LbdC!>{CyArNId=s(54dp(7#BBzuaY8?jufy` zmStgPnpU3Y+S=OM1eO4Q9AMSVG#Cuj?RM2}x7BPmWoGL4``X^#-UOE1F)gf`*=sW+ z#)z3w6a|Zmi<6o(O>cSr6G@Wby(dW$vMi(1>CkGm4j~_2th}9>UtV@@nkAk+xY-;z zAxV<4E1Ywf*&)EmU%$NexaOQ2%~;?ZS9y7HsvVLf!8teCPXL&5Vwn{`9ump~{5;Mz z@X5m8Gx-NJ1XRw)P+&z3MNzfi)BpaF#%_}@J99_@SqVgZeE}3mPMzk`-KQgf(~Lq+ zHE^grpz4XUYa1-47pTvjWcrrICx3pvKJCDh&Yol8#yuc{goqS7_vxoKQ21lGv)3LW zi4Z~$2q~4MkQ4jwQ0So0MYd02b*e#*$A(}6F$T)kF1@{P%ChV>&`c?iq7kc~$T~xa z?Ngt1kh!5F8K^?BqTZ-6lX;W$X4pb0IRdg4vi+e#2jXA^>!R=rg##3GP!2ZvRHQ0n z+xmO;s&}G6Ym@RLIIS>4_D^{q3B6vEDiyAvGHkpeHC#BN8{LcEx^4hiFz_l Z{RV0XY_dNf>kh&a;2ZlkWYymR@qWf#HF|^E)s7jy`z}ZOho~ zD6RPe)NA9ojzH4Gk3xn@`KmX4>cNY-Qnjj-!{4&mf-ec!j7O*V1huJity15lFO^;S z6LWhgn1tsBYPgD`r^MO0_0f-fr4$J3gp1!EX7%ws^!t{uxyE8+x<6QRRo`Hh9wi)U zgR+2l9$F%7l8qPN#Uw5`CA>`qF8p{F-$vZGdxCrK+3WbOLoS@*SmPWcw{Icz^ZdGU z{gg+l9I*)|$sks+y*d-sHl5`LdU=s(W(uFbM8NI>(3<4CYj>Uh;_URR9!hdn_vkDv z6EDqRlP+$y%*fLpqEO8L@)J4JCGY3ZCM9+Xw7xpZiEn;BaQyV;IgixA%iqS(!><7r zL=YRITW7G*Rm!;zjm0KylOn3irm>^^>Gc%tHwKP!zct0o0iUE1$CA4>1~l0uATp(*OVf07*qoM6N<$g6ge~ A^#A|> literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/folder_picture.png b/base/resources.pk3dir/gfx/icon16/folder_picture.png new file mode 100644 index 0000000000000000000000000000000000000000..052b33638eaa0f870a255bfdd5df5b79fb01a89e GIT binary patch literal 713 zcmV;)0yh1LP)Sp5G=H^urQrsC0eOy7edOd zZ7d~Lu~=e+5HQOw5_MxTbLZpEz4x5+{#{`tTev=tN#ehp|LXfMhP~b!qlMPY3^O+5 zlq{J!O})4fIKi;rd-I*MTbsRJ-?(RkrCAgCdT00TzzNEVZm-w3>$fIc-v5w|;a^m3 zm#KyF08Pzpe zb7ryOZdEg)0T~jLaO1mYch`nz&X^V4BRa)fD-uj=XaCldc=sB!STP zt;b%x&@nR*M+9c1pMS(1#*56;r$6GE{SWx%#sTA(KPSb605cl~l4`u|Hh+9WZdaff zVm1Js!Vp(~d!HC1SK5~L;STM!*NHK5?u9Ez5QtXDTXMUKT=?RE#qB-LTE(49d%VXn zE5Ley^+2!)QW-FW3lrJU+(Od^V#BJ zAQpu6Q*3UZXLH;6hw_9p`2lbCfQaG@q-RZ^I>Hr@UQU`nhdI;qPXi?DsEmmZ5T}!Pu vECtogXE(on?K#A&7z6%~0K44cy2R4oP`hnXtk|+}00000NkvXXu0mjf(HBcn literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/folder_star.png b/base/resources.pk3dir/gfx/icon16/folder_star.png new file mode 100644 index 0000000000000000000000000000000000000000..448e46fd5ac04933a1121e0d07748d2894e93940 GIT binary patch literal 755 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 FV1mw881w)D literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/font_add.png b/base/resources.pk3dir/gfx/icon16/font_add.png new file mode 100644 index 0000000000000000000000000000000000000000..b709ebaef4f32cf6551275bbcc3413ed5f51b75a GIT binary patch literal 634 zcmV-=0)_pFP)JJns=rXO>fi=YdvYp=OyIuL^83ysEIf(LtP34vHf@P1syLa4L>s)tjLDRY?|E+S*&m<}gEDA3wCC|S1 zC~n%F`=*)aLx8xUX62**Ryh}!5;VXx>jJY=!}V2J^Y4E*NjsaSAA6F^IPpwJ<+6wW zU8=5LQujKb`Z+F#fckUgU8t^YpU|s(=Orx83-p>b9R3rvXOE zXGG&B-+ooO{Lz1}<{Ou-vd(X^%s98zwd(4Pig^qE=T46QpVsI9KeEN)lV^oq4T=E< zv8NgBOD@j_`PDq_3`$^y)HdH}T%GuT%ay7BFFf1zzkheu|L}g@|K{0}Jzxd;F{ikI z(c@COKW(O z#rEI&moVY>|A6M}Z?yxC^eQ{;6;QI@qowV8c#%)F;s0${=KMznn=VZS89-cmx6G0L z-n}d7fBUWku;%ui38*e0gnR5;6H z`2YVu10|S&W(GL4-*9m5zR~L0cWa7s=goeHmKzfsTW-vJJns=rXO>fi=YdvYp=OyIuL^83ysEIf(LtP34vHf@P1syLa4L>s)tjLDRY?|E+S*&m<}gEDA3wCC|S1 zC~n%F`=*)aLx8xUX62**Ryh}!5;VXx>jJY=!}V2J^Y4E*NjsaSAA6F^IPpwJ<+6wW zU8=5LQujKb`Z+F#fckUgU8t^YpU|s(=Orx83-p>b9R3rvXOE zXGG&B-+ooO{Lz1}<{Ou-vd(X^%s98zwd(4Pg-vb$w*;&H+vCLYZ>KBsBOtCoF~A`9 zG^2gV<=G&=nx~yX39Po5?5pQXZ2o`W+WY_CwH^Pzt|v5TWziw`K>00000NkvXXu0mjfI;~OA literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/font_go.png b/base/resources.pk3dir/gfx/icon16/font_go.png new file mode 100644 index 0000000000000000000000000000000000000000..75eba80d629fdc8279afbd40369813bae7548a52 GIT binary patch literal 700 zcmV;t0z>_YP)!+vDhPTEsU#vi5`}*=t3m zOG=I7^=;SgcAeD!1Q6)vqouCPiA6pkZI#eMm0J!{NC4PUm?hpST<@&f1R)!bRM!&q z1%jTh#a^c`HkBT$^xp|cDKystTu4&1uL89tXYt`@A7Z}-1r^Nk?%}ew0N})}Vd5!p zh06{&eLcPN&jvf|?%j_t-4wV@q*jnhLO~T6xa3&3{~%b}h$K&2L(~1#$j-4MH9=4J!Xg9B zNTQXxa^zxPJ{1%~3KZm(p)l_d4to5^GPB{!Eykz00Sx@;|CVORC)<_j>Qld@jDaZz zDi|uf)y66RB@EBLNAE=UC=&?9!`deQ+r~h(G`SI(6vnfMgxg){D+Lwutc1Si0swhN#FwOv#}l83ts6rCW;r!9Q9l zl<41549yYiq6clJ;(J(YgF_14nmKFB@QK(mo6I~sr{BJxJ$rsp0HSt^ntND0Z;o48 z>O2Ckm9}n?$F`*>$L{;{zT>f+bCm7tpaqw^4q@%k z&cHHt3=3xZmt6rQ_dtDM#)Xwp66-Thu=<9?(zFvpy0gAr0U4Z3smE5f@pZNr!NoqT zEjSPuCQzMw(H;?yvf{+e;!7(;4hv)+d%cjKFiBL%egy0aeCof8z<>rLEjMsF|CBRH z86WcxAYvS6H;Yq)jY1Z-rrjWiu~m;clLmJlDAE7UhMJ*jBxp}s&nQkrZvqDXxsiv3 zSJ78>4W2GFIu$$+Ic&5Pq{1?zhIy(24enCZy35e>z6~XgVx$x%k(+>tPw)9SL~R?4 zs${`1bqjTFC3F)dxIIw>)!QP7$vk+;^#2c5r{lsjtwKYnfnn+j{~{GK;|I8rvPFU z5NbS#W7m)ofjNER&&ggR6fXi0xd4%4143#8JZlhXW+2TN#8b=5@L&-EUlY^cTT=>w zb_~+jfcRCYfdj}H0J49#sP#gtxE~%YBJiQ3AjMgoQJKuMITA}Iz|zizG7pw|7R*XF j=$D`QjOCK>V3B}dL4UFUkhgq600000NkvXXu0mjf1x-zB literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/group_add.png b/base/resources.pk3dir/gfx/icon16/group_add.png new file mode 100644 index 0000000000000000000000000000000000000000..06c5350cb197e64439aa1d0b1aa438b013c2f4a1 GIT binary patch literal 807 zcmV+?1K9kDP)mo3jW}i{%_@b6dHYnoXT!P3L{yXgdAxrsZYf zWtGn6Fta7-gNCWosY{E%J)~Q2p<+ThPn(n)hWUlVmmfdQ=X*FL0HnPnjy}$wR(mbZ zx1PY9#(k}c=g|-q=yB-J|DI-E_(_Vj+1;_w=7ycBOZBYY7odT8j9BROhpm@`AH$Wf z>4LGKJq3%}^ZUL4s_3JYc5^Qlhg4WIKg05S73L>;&|mCl-4}ow9>bk!$=q0)?0{po z6Dt-y>;nXf60Yk03E+~w*h+TjBEcX-#iFbw(|yMXVd_u2j*qWhg|HiPFH0JTB?qXs01CQi` z;2Ti-Qit3|Ed+!H^&_hgDCQAga(%sPx*A;3V83xD&;twuaL1LRd=9a^ zDBPBMqtckTdD*pHZzn)X`rMop)Kf&w4y3i{{nJN5&YN;-8f5V#Lb6Tpyz#;+&q^#v l5PBP&h9y_*-@Dw^-!JB5sxM9&*;W7m002ovPDHLkV1kg{c8>r6 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/group_delete.png b/base/resources.pk3dir/gfx/icon16/group_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..4489ca238aa5ca3fa16cca8789fbeb1907750dba GIT binary patch literal 827 zcmV-B1H}A^P) z^gW64MQdglX6sW?C*VL5#6(%7Cn_gWAsZ9nu_h6Dnj|#6l_NnJ2bU-(VpkyL(wpA* zDE1YmNMWFG><;oZLS&C5;O z(5&@-0`51qAgw|Hp`;4WhBqOUE~1fXvARLRkgx!e1^I}EFAv?(=}DcZ(7ekyocNCQ z_BjJ`W&!>%5Znv+cK}=k$@Bx=9%e9VTCsO6XPhF>O^uYP9LMd^<`M{A=n|`AZJDm8A+@B2c=23){C>RO^S&eiq`i_&3*gLFg*Ys& z$Fa~9xYfuDs*ec|I`rp#PnbtNL71BZJ=V5k*qxfRVDY{L_3R@Ot11jObuwJzWw0ru zU~NAMT~+Yvz65gG;WE2M4abNaTbifX7?s2Fz88Z}&YAZmh^5AH^(~n{*R=|G3@SKv zov;r{kjJ{D^efayZSe;Q|wDjs1pP)Sc{BUjR zEvRx6p>NAZE1wPtlR$L}1+T|g_&S$^&E;XJyT=(6E)4a4>E9#$sPVQ5aoWE~SGS`+216GGRQb4p}yUaTmb-qIPCF$G%mQ53R6(O+~O4MjS-Hi@Y*UVP^F;y2&VGtc+Y0id%HQI2~lo!JJn!zKG5 zFVI!z2kGV7Tj_24^S@y@$ZkJrpjdZ#q;wC~^2A@Cu_-|=c{g*U+yV-r4~T|TD0ns) zDLa6!Z2g%{30RK1Qk88&%+|A@ZY#vx2Ns4~1&}0|4Qxu_V0WD=V~4JMZ|7pUyBw;n z3Mi#a#NRl}`>%j%Ye31OoSS8O*n;IrQu{iaHZvpqmy|pjhAQKrtcpfmP5_Sh7z-@J zOm?gjkZlfaFk}aeN~X|Y+m=& z_X^5my&x-%LJ7?YOb-&C2V6j>n2f1j4usO1NNEWL=W{NCD*|EdYsp#_WIF3}dL?E5 z6jqaS5fj~PsDJdKqw*Tk>b*g4^aF+E2|3Gtd1YYaBx67niN*0E5PcNXCYxb?FaqD?0yJfwlr?6Y*r~mO zu3e6kQxIQO)xC^F8Q{|dP$X(p7x`jFQ{4R5+faRR`Ax5fW)%hoYnZ5iU>>6tbR=5* zZ00@&?UfQ_AwaHJ!NbCG4A!P$aWq>yUDfNZS;1WU5^_Hf%1YEGn2y!N85`*gWSmiO zlS1Gc(*Wul&Gc$OoOv0MGh30ynW&|AjTR-*hY3xH5YY_?QG`D6E?n>ZFMQg< UUKwzvZ2$lO07*qoM6N<$g6uMT`~Uy| literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/group_gear.png b/base/resources.pk3dir/gfx/icon16/group_gear.png new file mode 100644 index 0000000000000000000000000000000000000000..2544f2e637a3d3891b482d994a99b11a65526958 GIT binary patch literal 824 zcmV-81IPS{P)FgJR)_jt=7u%giVi!tIp5Wsn{YCIwmH&0TjuHt39I@th`siH>$zv2L%>B60ntAn%xs1DdBd8TgzSlHr59J zWINVeCV1=;6sKJ^{uhuz31`V!*H$D93KVzZeH>cEu;fYBPmhs@FC9X7I{9$a-^T^^ zIU*|W{GlBHX6)&BIqSN=Hid%iYOKkHR9TAdZUSbr866W^l-Y_AAvmkP$U76V1*oB2 zc0A`KqP^%Y+%1LB@u)C76~JmCpdG4!-EK#3Z!g3SA@s%;JTp`yh7+aO0?26O))||A zM`2d071Ptxu-R;IyWN2#vCwG~345S5jc8)pm- z4uUV{W9h}szkvN$#QC!P?5)B!7rkCDL?RLH8R*E=(;=&qVt#%e1VNy@y!?-OU#uZL zi8r!p_X48VM(`W;(CKu6;<_<6HwTqUg+p=5kl?OdE?=IQn1E8L1e?tUDKw#;O3gK| zbx!(G>IT?@K$;y$eftA~<`E1G44|i{2XaNdPbQNscXf54udff;+1aW9;0VcC8u@Fu zO$y!{511B!XXf$v*96O9v%V!u~mfrM_A(pRtvLg z6HJ#;mP>i&#lFtwyMMiJ3G=*7X)`Ly>RiQPY))aMg=|}bVy3ZtuFetjt!#Yl%f`Ic z4Re~Km?*ILye$Fgzdu_)(u##{63Zh>EcTF?ecgig6uX&i3H-coa3;$itbG}+#p+ZY zmL_!2cgP_Lxv2f8fJ3!n<+Cm=$b+dMLutzq44Xmu!^rP?Egv5mlA&)Dp-XWWXW6G) zoMO-H`$NEVv!vy-JXU3aRBTR(l!x5HRAlCfkoY7P4R6Yk)-HjK*t*P?e|+zTK+3T1 zdKPgFbxC2EtPn!Yr$Zi0gM#aU(h(t|)UIHc+97=)8Z~c=5v_}YON0}-A;@D`)Vy!k z{8gAHo(k!39Kw~3NN&0bhT;U`dbwbcp_nFp|6dqSeF67W=fG7ufK_Y@VLcty138GP zxr)ouLkN&EFkj^JTd>0+N029o+9)hi^!Uz zi4}t4t)SC+%}b3_t4N&$*!@6A2M}0v5>@>&s0|BL_GF=?JHsHkgMv;8IBG9YM8qc( z0bxswr8=$**5-m=uLrXgVCvQos9D4H0&`r+F$GO}5N?kTAf(h4k07*qoM6N<$f?!vBasU7T literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/group_key.png b/base/resources.pk3dir/gfx/icon16/group_key.png new file mode 100644 index 0000000000000000000000000000000000000000..257f111ca8b746ca6dcfc618cff50450c5b528b0 GIT binary patch literal 813 zcmV+|1JeA7P)^BE6mGC3Yb4)(b)otU zX3K2MrEJ?`KUdphf9?l9vwhD}G?g}6i#4aQI|Z?J*@ps(nWsdHP0rA&B0zL!LMwO2 zqRa}T`F1}J1xSKVX6lAiSp6)4d8izQP6-wUThW$sS#u~L(D!cSSk<%bwc$o=jW@wK zs)Vjxgk*-Nd|x1vY|qML-Ch-iks%4En4?1+`$R8df9m8M%)fpGU2_sTq>tegak14U z-r>YQ0Mq>(C6DE`l}#sOcS^F@$Sn{cL(GLT*B|38G}I`<;mEsCc8PQT_zsX2a;2j% z+8<5)hZw8jqMAd6D2xJWlov{exM+Dp#c~fDWp zm@JVDx#}L4K8C@(Qi+vOK9;+9n5YQAP@2d83rkN4MyJ9Lo8RlOq2*yiUx<}q9*8+U zrlg*KfumP*62u8{dkS-)K1W4~57uYWL41pWX^sOz!vrx!ML*xoL;^rM;$HhGkkfBy z*8{?OIg(0bh!>Tiwrv2t)lpE(Lk(+_3=q?PFwM|moS>qg?_{b7wWg75e5F(>yT#Z% zz6HS;5b*_Iv;)HW7JMoT2QgOwc#t1bo`+H$O^uY(x#!GQP%3g~tZR6&*&?F=i6ogry*ZfP4+pMu8g zM&x^d^%h_#fi49bn@d6%C-0y;#{<2>o7iuyq{+%Cx7OsqL|1B+()md*$UHU3yb+|O rzC?FX0Nx3`%|&ru4YQ>*`hLJ~_forVmOT^)00000NkvXXu0mjfWV&c+ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/group_link.png b/base/resources.pk3dir/gfx/icon16/group_link.png new file mode 100644 index 0000000000000000000000000000000000000000..c77ed8812e4523f5dffd636de73f257c5905ad5d GIT binary patch literal 858 zcmV-g1Eu_lP)`6pHR5;6x z&|6HBVHgK+>Y|If=&FlO7iNcxvUSio=LLOXuJAyRCe1uhAOkGKFHur7QOPVqJ`K#x zLsO(w5L;u_=1fOTr;z2bHRU1|*VatUY%2YWZ|k&L^Wwifd*1i?ZO_91!1!PC;{%1QW1meMY0UgO z|Ed+fQ5zPA?C?ILph-Sv{U?w{>=E1%9G|0-2pCgYE0TnuekxnG?6s13*Io$kLp7XL z={P9b?+D2{u;~vVC44vQjv&HUo=D*L)avD^xLb@Hm1-2+%0l~aBT70o2+H4Ae~8?> z@h6~9IO439oQCb%MT|7%!A!=3N@Af(9D%xlJeb_sxb0G))Rl>ru^MF9FCk14V*CkI zCIq&;?X>)LFw0c}dUpcatE?2YwYA7s zXXEBmC2l@fqTqTi-779Ff*@Z2k16UGu>Pn)MP;WiSE!Og1GlTK*addTcL9NY$ zQcGfFY?$sjolg4CC6^E#9Rra_1d5`dQmN=V zDk^G~&*wY*2uYG383F97_;~rF#fPIl@YUrgEY{M%S^F0pi#Umnjt;opZgh8d!)mpH z$z(2YIGl}sK%>ztFGNk3Ci@9Ft^xYv)N!WnV?W8kdu=`*Zy8}bMptC zPB$A96En(q(;yCWXn0pc;~VY4@?H>`4xHj9;(|y5sq8YO()6#SFsZFNm#>w{Wb@y% kBoqoivDs|T_jL|^1L{1O_lxzn82|tP07*qoM6N<$g0nk}s{jB1 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/heart.png b/base/resources.pk3dir/gfx/icon16/heart.png new file mode 100644 index 0000000000000000000000000000000000000000..d9ee53e590a68a95a9fa9483f0ebd14f3f25bb72 GIT binary patch literal 749 zcmV{UrO36YoGex>*KgTU04Sb0lNGJEiq?mmQbVHD$?08PR{#RY@(Jtf90i82`&dI!dW7jO<!P=IT3`*tHLxxjwl=}>+*)uJ zQXzyPPN^^yrLNn-L6|)gDrKnEAdbPP1a+KXt(F*+N-)2L{Eb_PQs+ab)QQT6Pw(ST zBha=K(orHRSCfHi4O9%(3e<(Lb`^!uF>+VB$3*L{zr`0-_;)Y*n?E-k7dr!rf-5ve?cY>d<{Q2T>(phfG`V$89Qfr0$5PaI$GcI;T;lseVaJa_ff4eP;K@^|hsa{cCz zXuY%j{{3s?^}(OQ^lJ0wCa2U<(RxpI&Wzye%Qu%q>x1omeM7&Az4w3Z$LrQ@df3^y f|6iKmf8+cE7K65BSFA1B00000NkvXXu0mjfxAtvo literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/heart_add.png b/base/resources.pk3dir/gfx/icon16/heart_add.png new file mode 100644 index 0000000000000000000000000000000000000000..d4195ff80251f62483a2759d15559b4393fdf7bd GIT binary patch literal 820 zcmV-41Izr0P)vjyOSSQ3)AUp#^U1ce29wLCXoZ3<~rO%128fK z0}dD+W~IH2x%~W(GkSghlGw*#her=Vh)6Lr`b^%+Nrb2QOT)rfZSjMDEL7%U0vFvMJ-kzDPtoKWjh)|`Z z(BmXQaZM0Y)`(VBB$snfb0O;_=Tt}0h8_C;!pCRVS|3cQ)dwe2Q+wyLGjT~*RU-#O!uzZQ-bG@-?#BD*t;1TVeO}3l^1*6M@QL y-F`A{5o^xUEUka3!M`AaH3IWe+Uv7M`u`JQP3y$y8AIa$0000(R5;6} zQ(H?^Q5636oN<~_=Vqm;qvn_jNl9YS<;i^Lsh~pa`Vc-8RQTe95=0pp)MG;afG7x` zg7F5DW*0(CMKrCvkJFgb%;en8{j|+8dMZM~zzsfywSie^O+=2Ss=nA6(o(Q8aspmulPB=B9BO->j% zsL=?d@cN`GNtX!}qv%Y_a_rl-rvyqQg4ozN;y(XVBD=^7Fvralq#X6cvzVq!kx{ zJ9MB><3(_03otxF?^IJ4SkqxUb`*gR!&i(Xvx2kPfVp`p%78|P6b1P71qM6qa}1dI zs=EY;aw-RcU?nOPp10`)rX+wD06|C*h*FAV#g|l*yjc&8_5`Y_lqC^lrfMXE*2(#u zOr`>#Ab^qr>p*48I+-bq2J*rHGSOflmVS9=25{v8u_%xr5}v0Ugj5#!R8Hx`Jmc+}`dc75$bX*KYH!9AI(^SPTAc4rNn?cWsPf6tU2EaG5rw{mhJ~$Fs}0 z2Odu-HaPf-_xTU1p&xl^mHWZcslOJzDKNS2T^&Wp9!ABP29#cGL{7F9A%2AmMkW^7 zMk{}7X|dCrnn+fov#Qc+&Cdniy{9&eVraP&)eTLs%np#TZveXk0b>z9_6^Omt+O!S z&`?c8j~&H@hj-N0Bu(pYJB8zqUVv4d-aHq+lZ%m|fX4nbOrPuO97J-Dyt(cy$YoOt z&l5+^U$SH@c_1YGpq4{qox}7jR@mRBaiXT?EcJ;i;+l7wtQofow#!DN!HdY6jD=NB zk$CMk``2-Pd#$XgYMs^AIOw1Qr{*Wn)N-{9ma}x2(<~`9Go1=*>YR!KZvrBS zCd!u}@M0og%Ev@_;Z?Kk>Wwv=%h_57zmt2<_1msz_niYE=YRNPpd%02TK9oK1z z>ooPno}v^sikz_|1XHFx_L%~;ljh7i(jiay5F0x*+(9aXXFCl?AdQj5XlQ65%sEv+ ztfe?|YcjPN*@yYtE~ImQh{l|#A6Z8iu>pf43Rj52CzU_dMQm|S2xR62YjQOn+z8WH zaK=!}ggOZi{4pB7SQ=xC0n|vXP_Bkx_a)FeNd}w8U97BNbSWxa^QW-li9BZ#M1!_xE*?wzt^GcoeoL*JGLSe_+l-JT2#2tz!z&^ z_s5anq&^nBklIMwRvcoP3%qs%%Ea?1c{_*V*Xj&~uLu-2Dp1fUN4<0zMo$EH>*U83 zm_9;Vt%-bE{_J_!If!1y=c+`QVZ>0_BPy z+%^pgnv`f8H)Z%0&Tp8&u*MCIC4igNW5MeWM_DHpDNi)Zxz|9XboOnitwFq$ETN=X zj-tkCJnz**Y4k#6_Ty^B=hWo~L!47r`HoP=x&3T1)JLr2t2+#fHP)9Rl#FaScf1rbdiwsJlF($-D2a$MB1QH?*P$(@5T4@;&OA53{ z62x9;g=MzM@3B}Z6q2JnuH-? zUBh=^5nso`tIMpW;}SD*?>znX))|eYdi7(c&C5YW8_t?tIU z>Ny7&^Pebhjth`srpO|asbD=?gpU+WKXx%hg}DA%|J1=w1E3bQW2brAk)glQS%iL- z`SP4IjX^57**EKJK0N;yU_Z*GguxzUVD)Dq(FOHK%^eAtSc;pSVFoq==$r8wjtx+n z;uq8_iQsA|i!@V3bf!VptWTH>59QQ$XGs&d#Zun48g&^nWN z^4`U@k2?PS6UX#XYTlj3cBYJ6iA9-|t1JhG+#TUO+}j1X$SI>}h@{JnYgEm?zETgA@`8 zv@*4YAa*nPx%@?3zY={UF4;v<61; z6D)OALEBso1&_@LYT2oCy8`vRIekVwj@98NEQ%grN?3p~P8P`6AY-Gg=m;7L4x_2$ z7`h&1qe;MppmR8VS3qCJR-)1wYXok8454Te;aC!$Kpcy<5T?yRnA{N%JgAqMSLz1WGJXyJCfGqV;Z)9=DNLLE5K7I8KkfOapnJlh(OD_X5JBC* zn)1H|BDEt^{K;vaxA@_q;;?VWFgWc1w`X~^yrHbIRB+W-Sd)co)#rT|Do)(rC+JXa zihCv<$u(z)If+O-3127yizf-|2VeAMC9&sj!h$nEFv+rVFIP s2~uH-oqupEvp6+Ik4^9qxb*+~4r~|rJ)t11ds3ds@qr4nTUjY$%n|^Ti@f{IBqDg00jKn)}CT24h+W1QNRMPc#1%G!B~N6M6;; zA}DUt^#8Y@US>KW95vIEItOe_0LFDcL}MltG|erD(-TU2`FrTD1Rg6*;_67UcL-|x zSASe>%m=de0(r5pJU;{JS+0iD&^Z-X*Ka_tdJX0c ze;6igSYUSr@NLC|uEZ#?iqHmsK5MxL5c-{P7pA3U7?8^#pR+=5abev_R%mpf{)-lm zKTe<}IR;Es8bBb=eGXPh=yWc~JuK}g)8D$F$mL`B>Jb>SVqwmS0(E5Ii*Ii7QK3rit5bbmhpMkx0S?gm)q00000NkvXX Hu0mjf$tY@` literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/hourglass_go.png b/base/resources.pk3dir/gfx/icon16/hourglass_go.png new file mode 100644 index 0000000000000000000000000000000000000000..b2d3a98bc4688cdfa1dc3ae3723a5a65e0e0df9b GIT binary patch literal 866 zcmV-o1D*VdP)EzKo)jY&y1zSlD`B1nde zmwy#mhVwyd0QaI z|0IfHZz3l>9_idFYXd<4)DCI{(lIq=m)5YN(P4E>hdI?c`X*M;CSS(ztQxWzHOkv( zkX|_~*eDwS`Uv}%ONIR^-3VD$u4*wczlMRyRSc1$`0FAvg`>Jx6~iT)%Ub~Y@H!Uk z%R1&|pJhuJ{h^`Dm7R0Q5XuMBDu(R;EN=sBq_9cR&@NY^ZFmVxfn21Y`E$;x?z8OR znP+4AUqErww4`%P2`K@jl@B%OXWlG3RW$!LT(geDg?ZTYuYf}Fv;(hIA@3etLLk=> z0dLO3k9`JSdA5isy@hwJsR(}Wf-5Npw2n!8&9(qI4O6@i&C|Le#R~ls4Ycx>BnbTR ztkMTjd@saQ_##Ub3%7!cuzEtRQ$;mB*4%~()b;;_VsVWwYjwb#+!J`)!T`7VCD=`g z$QQ>G$U|g`V&KEQ3d=}JaWIs!rCsP1W}#6chUCjE#%7kWpwi$*<`G;=Jp`we{kV{{ z2Oca3WYkCD9>*ES!i?1Bp_KJDnf~R1-P4`$WIN$hxG_RJc1bteXwaD`EF%gle=AJ8 sKor&zg_Twjl+Gf22ZHXJMsL>n7d!LPMJ&Eto&W#<07*qoM6N<$g0UNkpa1{> literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/hourglass_link.png b/base/resources.pk3dir/gfx/icon16/hourglass_link.png new file mode 100644 index 0000000000000000000000000000000000000000..ecc59b0abe2c63a263c3c1ff9cf35a88575c129a GIT binary patch literal 871 zcmV-t1DO1YP)Oo{xzq%%#lJ z5=G}XEzwPzy2?K1rp|e`oX6$dN zltkh~-UIZBZXYRxZq~-QYh>l)iwarDxtQF*vrYh5G%RYEnClY5JS4-4wgPLq8mvxK z!!lBaMO7h8?{h)6i7{C#0Ff68Io}nOfN%(=YoARV3zo;qD9W)kT!MuG8RoikK(=N; z-;fM#Sprm9A&ej|XR@c3qzmy4yd(3t&J+~WfX^9Kxxz! zG^7TgRGJQHU6->%KtFvmhuvfI2Uy#-Vein6eVZNYJ3ldH-ovPI7lyS1kgEr1*Q`R? zY3M!D_nA=^gtVHEi8Kf_cjZ{n9>Wsi6An4-_d)_JR(B{ABo)fTmUZ-K9;t zMSdi=VcIxk!ky#mC{!9}BptIZzlZ-298*8EGN>_HF>2U`tlOyi+sr=&jYG@Beb6Pn+cQYO>;Z4va(TGS&7uN3?!HLEeNFw-^9d3lJ2FYrETzdyr-_N zu4f$K+CfWe6R~K|m6jquKOYv01tdvgU|<00uXB<3Di8Y4UykS=K@iLgo6XK-!quuJ zWshzh^3Gleg+gd_I*7&T@bmKnhr@wHB7s04U}|4B+a44Y)JaPc5)!sp4Lv&Nx1KIqEP)v;U&v3%|^C`Ga3?LtY&4dQB4Oz;1v;J%z!D&%WRH@BZ?x; z3)8@IUIv@hG|@IwyHLC`l{1<4BK>wam95g|i|?Cfzt876&-Zx_0f5*l-9`IJI&mHu zE6$@xB)6N}7VeR;!X8D!TAw;;&0Bsj?A071cO>X3K0wl7WZ1;Tg!4LHyNcnzoeQ7t zNW`aSlm8WXYkek&ir$13=ngczvf zV0vnjNpCF&K8px}dunv+`LIb-sOC$_jD(;IBI$xC|7`(+9cA>Vir_V#z{?k7SX^Ah z^71m~W@q439Ycqfhi7+gp#A14n1n1!e>$EdeATG|f798Y=ggzwEKH2Q!qU2QA(Se?dwqG69%>n$6rtE z%F(845Az8c{w(XgimJg96!jLMz?zS6I1HUm2baqQx7&@nx;lhHA!r6vs2|fqJETOu zLxeu2OQ(3(au%dg>AcZsWI(zXn9XJg1cLe8k~0h0wOL=&HK}7X k{AKr*U4z7Szv)i%9gTgghwgU$Q~&?~07*qoM6N<$g31kYk^lez literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/house_go.png b/base/resources.pk3dir/gfx/icon16/house_go.png new file mode 100644 index 0000000000000000000000000000000000000000..5457dbd3cdfea5274b7c38c9373f4e838993416b GIT binary patch literal 861 zcmV-j1ETziP)XFYYOQsT3iq4v1n+*XGK$uN_ml6wuh-}MeSh~Q01%s{EBOdX$6CW< zSZmUq$gTEm39ESwqbA*Pu_w!UQJa0#sLgdF|4X1waUf~Xq?55Q-js;f%_-2AhoZ0G zn5nPOll-SZljcbFWICIM3lC zEEtmy)1j{jgI45)$6{~jDx)ygB0#?)5-ogB>R!4Bxk1pIqzj_-#Z594E_n3B5+myaFFO8t#FTCz}2nMbp zxtjxyA`V8Q5uw#K2vqEWU+FG*$*d4pe;ieVLU0=WVJF&w@Y(=4@$A17^yGm+h3{uC zp}XNE&x;Da8uXRR<$jPzB#=s_pnE}aaWNe7x364K`oT8Ga>ZTXFhRrL4qUPsAh!CZ nf5t{Y%+1%WmpxfLca*mw0K_85Qj7(Qf zhc;c}922^zIU~GfWrBWCw_J`0J^kKa7w|$a9C$d-dCvR1=Vbw4?T4%U1l6aETXC!7 zqXW8xsHf)iil^=jb(r=5(N}Sjq6b4hD<4yxa=d#|fk2BGL-nblAxj$dUjw%)o*K|5 zgvM+FOm``1s4(5FLGW1({Ei|F)Tf8shIHys1GnZBHK0a0{7;Xq41f=)fXY9Tzgxp?#X71r0+vAMa4h51=@YR|!G z6v2B>frnM+VJ(OYTZFL`Ysio?9%#Gx=baLII2%)wZ?Unl!3_V!{M;-Y(lp#x=AgH+ z7_HJw)No?PS#+{|k0pJ_*DgVyk-hur#@ANjK;=BhNF97xm;ewX0wm(F)*9WTMmZAWBP1i2yR049(5W%od~; z2nCSH3%7_#rMmJviyr=}?7xB9kxGav_%PL*7z46;PEHQIUN0slCgAh=(9_d{Y#tYN zUNy6Y!DIl7zIo(=o%1Ebm^_|ZkQ|kj$##iBNl6K~TrPM#9>iiX15$Ii9EggAAz~mc zlm6V3!EySCM4}Hin{BhJt83lqbTV&OsZ`8QkeYC$M>Isc#~>yq=15jnRzhxW?vhk0 ujVKg~D2*QyiR226Y`XqNIMO2;qWuMC>Xau@Fa^s10000aI= literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/html.png b/base/resources.pk3dir/gfx/icon16/html.png new file mode 100644 index 0000000000000000000000000000000000000000..55d1072eafda48abb0a5fcecb98b114d866077b9 GIT binary patch literal 578 zcmV-I0=@l-P)dis)>+`f+#3Rv=dSV4I&~|Vk?LiBG~#L1X~NSQGbAyogj#ie_$n8 z*oYwUieR#5zw>=_v)By?+NE%sVPM|5yzfjE5$wfk_Go)9(A<0e{hvFiJ0eb2MFf%t zDJxl&RDw>Nl#~WweRba-&_F#fn|ifCG!S=00#QfIDe64k{5mZFusu=CnSq>Qvt$j5 zI$4b(K~|@Tvozn3#yaJ|Be;BKfh@+AwFR!7UF7D*61OfavvGQ!VN-Ga+zO*%#qEoS z8E0dX4NpRyRS|XCrXq{e4r(61{zg^7gBPDUwmjg}k(Q%NLkD6fm6*tZ=)6^ARRw9CNHr!!-b)EovamKwdDMpr>=!|-tf?S+boQE&JP}G_9P5@nR zSOjlBPI$jHA&U_KsTjQko(uJ_ROpKn!K^ckXTHmZd+_Mh7C&~BUYvvb=Xi2w6%i+L zP+hwJF0QUE^66)$h?CXHvdjEbu3a_69GS^`e5Gac*$0~K9VHcGVKhe>RE(rT+Ca5J zv_?D-3(OpKFrQAl`$E;pyKkaTN=V?@iK2u!kqwFy=F?aM-2b}R>c4;EZ`t2+*gqpJ QK>z>%07*qoM6N<$f@8}2CIA2c literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/html_add.png b/base/resources.pk3dir/gfx/icon16/html_add.png new file mode 100644 index 0000000000000000000000000000000000000000..f1c08b7d6895600e813d05db9ff339f56289b9da GIT binary patch literal 698 zcmV;r0!96aP)GYch2$-=^h zQVJ0^k`=iwScsT0WZcd--+ABnd7lTRY!o%WUt(rVM9KuEOi*_8;z#2zM3oQ}Cqf8N zh*3Df1)=ap9+aXGGJaax+r}S;s1c(fYDhGK7(tZ~j37#giWlX~?NKs*`!+5_1yMty z;-e8n31WCroJ4#uoG3mhoz;w@A*B4IW(@Y#a3QjxzsA<(9qd@y$nHnKc$&TqGsvA_1`Q{e zLGB`|#<`p4>6!C@!GR@oclL7U*=6oOy+D2X3zD_Rp4+DW4&IJAd{CSyE*M@ECyE!P zT@SKl<2op%Y+kgVp<8<>k#gbEHPUb2g~CT_ttD!cO0>6?=%|*cS4&K*W^_#{^QAFL zIjORF(SCk8xb_V5yZT7dKsHtcPF{V71w)-;Ua+8;i{KTDO3&iYJR82pqv5+88a&7G z8@p&NRWL1+m>K`FY~QS7-SgTHujpGv?~Hz4zJJKQ$9H-A>g!NqX8ez3`(_;n_5wBF gJ8Bpk0QT%*y_loy;s5{u07*qoM6N<$f-kT=jQ{`u literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/html_delete.png b/base/resources.pk3dir/gfx/icon16/html_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..1bd28489e55af96b73429471606072a80143216b GIT binary patch literal 688 zcmV;h0#E&kP)P}pU>|WE!{&llBw4ut;O*J;G z?4X<_99Tb_)^ftJ&2y={NW(?62&7JgAW9`ma6zfGq}+P;gCv0~55KdZ*20SU6}qZr z+RG_R=2Xa=ks>IX3t8@jrYMz`go7JvWNAX~1T&-VBC626yaNN8L8&(*4IgnK#qvm6 zFAV3E!YkJv58_2>G!+B#W+a;N{%eB|cdxVd-d5i2Yv)Msc9wm-jXF>EtMD{^8)i&S zhWaGuE~09@zH^nG>2o$6K2BxnDvEbc`Oy1}x7Hxpa_OV(T{DYsqYfVwCyEPyoS!(? z;l5q$IeD74&o80B4`$3{BwNgrC!fg1#)ZO1I$KNlmW0-j5Gsa9LXec8Ml~Oxb>33g zb>{B}UYO53ev*wAfg6wev0$iE%nKG2a}m5^QQ2Cq(s=WT_6MhM#UKq}e5}MsQX`p4 z8vA;>E|fdl&n>J;mZjeq9~Qn0m11bx`DChbe$}(+Y(6@0q7;+Gv1I)QH+MXh%fA7S WOLjj|mpRh_0000a3s>5r;x& z)rla24@6K9wNMI$woo;;iYcWgx##Y)_gZ@`GY~rIK*;wM?#@D#EKtb;Ri}RV+xZ`A zhKLbW5rLpih)NVCB&QZ51f^o$_?kuh$5C@~cGMirj;JGMh&ZB#WFx6@>CS5^-kI$x z*+9+FY^3an8lp~8BWfmz6V*s!vxAJU1LZp>H^%BYH{(W(lf7_Huti#Mk!3i$5YD@KNTS-ZT&g}Yxe zHM@_MZK#_}5W{MvtfSJX(dsQYuycs2EU2U6?sQ_t493?C5H&F}yq=?%x6n<2C>gIa zRVO$x86g?xufOKlC~WES-NBtwM=&7 z)yx#_fo1&o;yw@m_=SJ(ougQF?1?u)ad9jfo)i~jV)6)0N+e4(npicwfo)@Zc|7%i zTR%Udes~7&j8eEe@8jcd%X;hRXN&LtcKfeneE#yR|H{0=-FY8lCyP2;&*ETtZ2GJ} a<(;=eRf2_>Pt-a90000 zlh11tK@`Wovq_Uwo0hbVwIoqQhQVnOkuXz^e{MG*vVUi||+dlBkEy;#AUC>|=7 zf?$Pu5)ttv6zruGW7H~Y+hl*t%+C0oNdv`8rNb_7c4j{Beczk6!di>1jIoC&E-I}j zga0{vb>>p_^3=Iw8{l!mPbve0C9#n?I)01xKABiqJSL(S+| zhYX|#jfW+z)dw)reao-^_+3J8mqFCfEeD2$Jaw>$>Gyvyez*tuj=%}wV=-Tg@#fPS z&L8Q=)3?Bd(LPMfd_kc@z(k6vXze5Avx4~=58r>a3?YEqGhb2d>%hLjJSx38Y|jPQ zUCyH!r-*pgG^wDOXvEF|JzhE9hio9=*4*_rk`$~dYt-cgAtuxy9Qxu0u+0=fBeF;& z^Wl5v#W$aC7#k0`NGTnCTne#J4+*7kZ4=Q!tSn3-5v)WKF=4mSiVQ~9>)%d+#l4qx z{9MysLHD){Ca(=cac&a}aq{N8Jv&lD?NH*Ie}D8_lU}{{dpp^$#|VDB0)4P3h)NUdleE mCFsAYz*qF2A-4KEx5r->H>;=VK>mmT00000oSgT$J*kO*Aq9I~CW*s{G*(t$KS{OS+#aO%?udUme<*TTEO`Fr@r_QT zk=#}u-n~>Vm!+9S1PE{@3<)G~CPb<$Za;W?3+O}|+q)?*Pn355=}S(XIZmEANjZci zf5 zj<%@MX^bD1^BwlS^+AD|$dm-1wial0hwPI;CDM?Y9SXW#@w-UF0SQ8OgplRTleOB2 zUjkDS|0U9pI|lSN*EvXUa~*UIclJdZ#)Npbwh9>YT?Z;=B8|l&^t~P~om?<5Lre$+ z;%`P>SL7`djY#8Y9$wv9dv|3p)9Ovu3r^Sp@>J&i__b$%mxew<#AEK)K4_tuGzR_Dj zPEIW+13!^2!Lpmfum?NCj6AtX3WL`1|z0WJO$R6%tkR)SoHv)7)V z2J!;SiNK5OjY!w+2h{D`h38lT^}tkNg#0yvV}#EiXX)>`NH!2DT1ckB7?;L|{Tz(8 z;ur_j0K^3mj0hqIV+lr?y8Vsi$6LOTA8J(bfmHy@>b zcO$Rop0fUa(vNo6-E;xeS_D{{pDQU43O%OnNC$xlI9%J##D`I$O)boS8oT7?XD#2H zp@F_)^gFKH=_e!=bR0Mbz~#1kjL!}OW4;TpGi>5Em#V5QmwXEgf`!BCTAaDqG;d>5 z^tO*M_~HzHzE&w0V25WOoga94ESc3NYfJ6YaewCBwAXT|mGRkO%EV>r%_P8({OdYL nyXyvlE}#-v1%_wt#(IAOCI8(qh6s|AZQ;I8AMQ)(8AgTxri_~QH!8j7P*R` zMc^VU=$D{HL=sFyKO~Ajq>MlFfA48AXxr=Z6VbHN*b1^Vu&p;5ljX0cxTq=?a5f!hw>Y;n!k*~vFnseWh_8s^dl9C`3w#?js<@l-uiyFgp|$5{ nCx+WSD{<@TkixBf{e_-iDvsiFH^U=e00000NkvXXu0mjf5N;`P literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/image_edit.png b/base/resources.pk3dir/gfx/icon16/image_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..0aa4cc6512ea19fbb5241bc67ba90a9f8243c960 GIT binary patch literal 783 zcmV+q1MvKbP)5LVcnTf5GZ5SK z3kX3yRAdV+P=@A0X4ocLjyN{1GvCa2Zx4f0Mm_b1^KcIL{`sAI&kt=e|j1aOt8IKFRjAQ%V;Axt!&Q}+Z~gVtlY#!Wcv zuDrJsNE(EPTsx2x5C_g)V`_dDwxMvf4bqPkBtr@eDfrsf%!$MMiMv9iS{R9elqSVR z)0tPc5JaRzZGN<2CWLZG!mX&0p=0>~b`OL3$D@B9k<{xM9y~l^u8U0nz0Se4#tee$N z){M2pzFo)T6MSiGBQmVDbov*_F?_8-8Xlx!C&Nsmz|%-Y$y>6D))DQ#gs}Rt(lhX? zJ}!P(GQ9L)ZM*!P;CBTF9ZtvJrWbUN$aV3ZxD%gJ#8B!E^50fauc z(%JeF*;-Bc6HoVctJ% z#J}bQxxs95eQ_-5U|T|`2qxI_#-5W8myg8t{8iDA-)X%=;eu5}di&_8f3NTO4h{EI zwYbm%fNg=-My|PRb|Kn|y%-Jk?%Hsw>EplF`6o(16g6JqaoYd@ N002ovPDHLkV1gC;Y5M>G literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/image_link.png b/base/resources.pk3dir/gfx/icon16/image_link.png new file mode 100644 index 0000000000000000000000000000000000000000..4bdb3541ecb728c1e2b0bef1b0546fa0878c99fa GIT binary patch literal 773 zcmV+g1N!`lP)a^7G6T^gLQYt)lJ)S*4dqT-(Sy@A_4#a000000OYX$@Tp_vAnm)d zTn=Ab0RTV+0E`r@8*%c}_x2php{&yWw_e!Z+|X>MlyZSU1(FCNs6Z$OtDbrDi-S0n z!PBFmCmmdyTk*4u|()Gt$l9F|wevfQ0pZ+G_t zlWJK_L`lj?NtTk7GFg@xs%5GQfE=JgQ4AX%SxW=}000Pq069Q~{%TLZcb$|(RH`Ud zRVE=K)KY1%x-6mskOM?;d8zI1OH2CIKozBbR~D?6w@H8v#Z}k4OGE}B2Z-R}!VQKl z^neJWDWV79su3411OUjPLIhcD4HaekjK=C8S{rWh``jhH%@0e%ql)vNnc33t$;lIL zjwq(4rs_FB1W}b1fBoFOw}w3j59oHgw$9D@>WA<3t+DT^#}z}lPN!qd(9gqP{{%Ixgy^BE)% z9@>7F#!c(NYp=hf-yhh!cdyCGNi#Durl+U%2Ln$(`!X0E9W8QLHfXNm{_+qP}1jg5^>)a&)r ztyZg96h#f$;^N|Sm~S*1r!lm$vQoC&?aSS6_lf@j6IvVn17&DY00000NkvXXu0mjf DgX?L9 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/images.png b/base/resources.pk3dir/gfx/icon16/images.png new file mode 100644 index 0000000000000000000000000000000000000000..184860d1e0b16cdd0698a884186aa27c3b685106 GIT binary patch literal 661 zcmV;G0&4wR5;6p zlih36P#lKyR|!_HEbWGst|FC=iQ<@LbGEBn!qA~>^`=bSiulnBr?QncO;#pi6;Zs= zE5Qp<+)W8it;X7qG?~p1m)CPnztUmZ#RJJX$@_cqa>9+wNjCzsvg!_rnj_d^tc!C} z)Q@x?#ZBGNBVH`Zj(sOsLg54o9R~-vBzft{d=Q_JF@P(P4aH z5rNrN_=Fq|1VyW#8F!Fu(8+xAESBFc;{Lk?9=^Ycld&v_8TK+`0d=x@@j(PDA8%px zLle(T2Gs0LSit9aqRaK$cs>_Jscym*k~J1kA&H)AE}TlnF?=b7!Sg8)Ww^pQID;9u zC$aGm@=IlOFc!dpyQG98;>{t z;K|p&h|8~-wr?s6WqcIHcEDgr+$@!=(1_vy38012hx0`X`ENTN=o;1bhSJE71W+tD z;G84@$9QRBXj*jSA^cvU--B7JvbhUf_1^bP? vP|eszjZh`mO}g5B1MG#;NxNxl+u!*If$Q>9A-BVme|mWaqy4$_pJm?y9KM{-*hp?1+Ey3e-CEDooTa!B;e(Q>TSF?bj>5At13y1p zriN3w3x~5SfZj{@J4M{kp{?=M_Lh2bV+5LH)Q)5W!-ePA$RgE1@5f1cyHki0Y}JyVEYZF(LD$xXlt$7A5CgE@ zpV-&l%vf;=5kZ2-2gi@Y6J&=cuwt>!vJ^#(&n|LcZyUzi6Duj$$hJ1s*HD-#;k-w@ zpdrwAuoDG_N2bvb07G$Zk*?Hc)JLtW4yqOnic_$zO7NZ#l>Fm){;fE?b$IbOaX2fe z0la4g0Dfw2xk7Wi7NapVD8YMPCZu?A1QCK*67dgsvRKBLFtrM>?$%&_lD1882mzdO zWPdw5KWw6IT`m1b_8=lS5jt8D3=RDa=&jWzR-)S@56WMslZ~mKu1)-wpXB>rNBQ>N zU#K`#1B&v|_AQK;7I~B}OdGiUT9LX>f0xm6<;LeP!=vFjPsUQF*wCJ*dO)4YBypgdiuF!=i@6Zyi7F|q#K zz?tlSZULa@t1D?$e;f@b36&N!V2mjOHw|*qrt0hl7pI`Dr$rJ)1%#!m}(}?)Q8C%hu~P z&*$@ZsT)vdK!&|8zes6Pj1N&eUReJ`yuV>;nnucw0cwRZqU);x5X_mKSbSEdYhBl; z0GJP%irE%X*WG{_OK!=Ch zOWQ$|ChD2{a5$vx_S-*#TZ9g))rvNojk!lrL~$Hb5CpB*=SGmFLUCD^mceefGw-9( z=tP6QkAZYflEgU9dV%b_cLe+t2B0bK>f?^+)j$Bo<1y*ArlKh97|`KY1}?y4GBI6U z5vSAX{{X@;G!77-A;&D8M}xOCP49p%jzo#BYdscH_X9`;wbP{~X{rDK002ovPDHLk FV1mD6$SME; literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/ipod_cast.png b/base/resources.pk3dir/gfx/icon16/ipod_cast.png new file mode 100644 index 0000000000000000000000000000000000000000..6f6d3406cb1062c517d384639dd27c4cc22eb48d GIT binary patch literal 711 zcmV;&0yzDNP)D!zG=Q}^X1IIGPP@%!z!@w<+I){Owi4hXU{7EgS}yl zc|){1MO6fra^Nn5rN9@UeQ+WWuYp1y7AD>y#AR;0_H6)^>LFI00w6c8@D^I}-8gM` zEiQFih+>?Dsa7V36-q&PdkRr}vYO!I%cG!&i0^b*o=}v$gIIDN>EFi$7uFJdKzL74 zejS1MNqwV3W=NrfrVz^SBARq4&VpBJM+=FO--#s~DCEJhAym^$G2e+0XHb4Svt#|# z?RS_S>9SGY>fMDo2;46OrQ3vSisXLvu{6^{KHI|dk3QnNipbJ+lsm}cv?RI>+)^rp za2votPy%0wkv(lWOY8B)+VdS+>rSN`i*4Im0{)d?5lAKy2@;9KM)=}? t0ZOTKI-PD)O4XNtV67Ik)}J@}{{WOyO8m_F|55+|002ovPDHLkV1m*nKHUHS literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/ipod_cast_add.png b/base/resources.pk3dir/gfx/icon16/ipod_cast_add.png new file mode 100644 index 0000000000000000000000000000000000000000..c3257f5f1e2987bc9ee17954cb2623367578f778 GIT binary patch literal 796 zcmV+%1LOROP)MUvn@5JJ+GVOV$(UKosaQ4~Q%!7dWiGJCPo3{GAL5i_55R32!XGq!Wm^*YDRxAkYq2tC!GUUX}>pbx9cO zbYt8Eyte^d2jF2rT>)n;V808v6u@XJ;HUw*F1pc?oAd|3X;pYj#R9;micz7Ibdxtb znah%)FP7p(Q4BVM8A}268Fn4uZ_9-LNetm$DrRG_*QLQBPa$0e=>}me38MR|0=j|} zXwRqN>A4vCDgouO7+7frgOOGh_%6~@3%XL+?xez6IftP}z)}vFZ_!-=bjaqQKAnok zC!_?SF$#gE9F`&7j|iLAXR}r%lWr|s^%2rF;8~so?J^1J8eq5{f$C@lT8`{O!{Jr* z(irlrX@+!{5vDEoQ#WJD_8HE3^Ml{+2!%pld7cNyaq#>72oCjs9(50}sL$R;g$wAt z4cywa)Z08BISe^ww6zy^Su{UN5#tb^QK0Oynj z?>>2<9KHsbG85UwyPFdL!n_-RPX3FSyobjz5K&=ZhJGYE&Av-e`YsEAp9uh;&nE(+ z(dcGQR%c;wN{hdbeNrO;kO1&_JR)FzejXDO6JjK#d-2G70S(@KvADsL|9=CQ%e4@{ zeT}UiXPftd^%jbqgLXx_EI{ zrKMEGW9*{2Sf;_Sa^d}jOm<7w~Tld8ZU$6A~+4uS^^E1pz4T=@&l270ZN6D*P^TeJVsR%^+Gpl?xn|BQJ6CH zJUpsWFJR`=P`X>50eJ5w;=QfnuN7rk#c?H$hQer}YY@5}m@_+gblgDYp=c`h$8l$m zN?k78*sdb$6C_$njQFaAUa6+5r~X1L_S^tX*T9+$kI#rR2g=g|lf^*S0lJ3D{)d_ELK!Rz(X(PaD5>Uttmv_4D}hp9aa1*=CS zp*u;(1E|i>wj1g1^tDe-P4U0DTu+~ozg9=#nvvjWmlA$TV!H#>HmjX_?S2 z8|nk|^1)U@>%QgF9)0+vbMFeqMVXRR$ccfXc!r8M}+M35Z(54=eI0P!Lo3Z>vVl!7-Qw}2O= z3LZ5%NiC?SQc6r%jpSp4>1IE(`+PH-w{Ah=0JUDw(Ftl#gmTCG;c22qy~8EyUh2pEt2jNHcp_?KUsWyEB^ z5r7+Dz_H9s0DuogpjS(CNP_FSRM%d7dJhcq{p_o?Us8a|b@RgEt_9njF(`+UVdtY6 ziN^$8oJ=OrzW?NT3fvWaY;5qOOM!%`o=i%H3k&idDVPrj0fQ6j?;?ziH@0K19FBVz ze_X$_NDLA&0FPI;hwdKzeqIwMoc!=Q*1UYP0+w}JLS4cf$ANCQ3!0`8-8wcZd`>=*&{n(n(H&ZS7D9~VA-qjs07hjXczMlGufO!-eHz~S57b({Ty!0 z^|sa|9GsAVnvr&^)e3>|OaNfBx#s55PVQ6(oXK0-#3%zC7L54L4{ueldkJW1R95TUzXcT$G-|YwZ3uzC7C+PJG?~lg zv_tF}9Lz9`k3b+0_INxX0$taGolfVSr|u82E+>M?WOC7HG|+4|1%cb`#%MGOIbj_M zI2hS%mi2l)L9kpdg&$2I%d&`!F+pIF98JJ?fOI--`g}g{MGB{HPUg5ozHumu0!fn4 zYPI0^`%mkDgH5_o(=;ga86JN7P;YOp@%r+`{n@dDa=9GlLEG(iGIue5Fc`$0xxvNb z6PU4NE4`ciE`KK9QmM;Qsg$<~sF({%i$^+^?KoQxsb_Z&~CSx=zu3>E?rbA z6%vtHm{mkRo6W?TzSB98NQh{UKnc2aI2_s_t8l*)3rD)3UuzRkk`jD2k+1;!akJU{ xbDN;s?V?_<+oCyiON~@Sqwc?8=JcFTu|F2lW40ifwh{mU002ovPDHLkV1k___RjzS literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/joystick_add.png b/base/resources.pk3dir/gfx/icon16/joystick_add.png new file mode 100644 index 0000000000000000000000000000000000000000..77e710772f40faddcc2c3fa16c4a92a07347d052 GIT binary patch literal 669 zcmV;O0%HA%P)oJ(_x`dc-QTAF>c@ApwG7GW}(_5=eGiNtt&dmG7Q5)@Rc)nG6f z4g>>;+%e5AmkXUvhgYD}>4XD~uO24u{cfHuTv>!2!Pu^1Ezg>ZnyVj0mdBudbHYQy5W6F+U%V?2A(Bf)G0G#ZTy zB-Ye%v)PP%J`eJpSbARI_>eT8e!{xN;mgh2FdB`%Qvg~_YO9800000NkvXXu0mjf Dt8y)8 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/joystick_delete.png b/base/resources.pk3dir/gfx/icon16/joystick_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..5d44b592503becbcba424255921ffdad0390417d GIT binary patch literal 671 zcmV;Q0$}}#P)*h{!Z>@B+0F%S_t zL=uExOSA(;co2~&X01@7)osa8#~DW*r#FwZkU4B0e0;;q_x;{`|M@>+nkFVAnM?)^ z!`SHcdP2Y7ho))Y6h(<95(#;-*8!W*b^W2=?-$%|H!MJ z@qh}+(t2kXwjxr+A&MfLPA5vG61-mT|LuS_o7Rf5EJIW~xVW>8jgt$;U%q*tj%Kc}BY*Or!!q*AGSOef1o)-bJdI2`7) z*(?f$0;<(2JNK$M4{_lHw4Ws?o3GLRwGGw14`pp?eR;hWWdKUkBasMC0cf>aY>>Kd zoc;IDFjLRt*x3u1nwy7K%Hf0b3QhUbEp`Oj#8c}clgU^nVuGovItHBn_ynhJ+=c7Q z8$h}b_W=)%3bQC|ns*$3L}RNq8V&Y58timBtnSwpxO{WK`Q^XjtsVw9B*JJ13=j&1 z*gv<7^KaFEJcn9*iRl;Dp=))hmfc$%3=UfiU48N3^HqQ=65>v_*`zV_8SgXU*zS6%{~AC002ovPDHLk FV1lFjDy{$k literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/joystick_error.png b/base/resources.pk3dir/gfx/icon16/joystick_error.png new file mode 100644 index 0000000000000000000000000000000000000000..b32149e27a37adb1c567ba71ff61364f380138c2 GIT binary patch literal 711 zcmV;&0yzDNP)d&Xs0pH>F-Fp)`Pg*#IlEx0A%{E|26ktDGjHbqIK~+IPb?O* z$g=!ik|bNV+eNF@`qpSPR>I-1*dIHJ0jJaHJeir9u?d0z6;LP?%=vu&G5xyMA3HJ# zP_Ngg)9ExanT!U|>-DJBYL-E<0|69_jg1YiR4QqJcDt?F&;Xw2HP3OJ2KWmZ8bC8Z zC=_BwqY*Sn&D3v018Cy#dcB}QBAdJa~xOCSge{VTu}$c;~!UA}|8w@<<3_TdoK1a)ZDYE=U?>NVK)IT$Txp)|9U z+rq+i7Zm9SsWJzf?nmX^MrbE*gmZ6|p*GkKoxa?X?hD9M+@sRvFH{EqYA??u6x z2pu{uGnrwz*>rh zfvUA@7b#acN?M*mBG3rQV?e^+0R5m3YXWyRZL5Bt@3vAw{9JaEW$}=f4bXO52yBH{ z;G~ZN|GLn>k~{On3Swd-Sy(gFkOdyw-RP%&exwl01RJRp))TI*SsngruhZksQ*NT%!X?K00007oX;fYS5fR?a$bad^&iuHSu~`3%VTtO}r!shMd`!61c%6R9aJGSh8X%)P*raU)hwAiO6D z)GH7M>Os=K8*y(FIo?C~yJ{<%*U%nBM$Zz%Wh5q=k@+A)HgpoHzyZX@8&HV#!QWjA z`_+cv-}i0Xg^24s7I-VE#u4*AQoR#N?{>t-#LOH})WMk9;P)owvi_IE6!o^=Lf3R#&PVCy|Gc4obnhMMwvBLinP_YpwW)P1ST? zrfe04-x)FNzro&t&e;ir^8^J56p&nqIY_fO@GcRuAKQt!4<44sunkb-j=jm5S_@$&_dyonDz^$r}kLbDn<^FJI)(KksQ7G*l%&dIcv63Kcm5d9~ zQDnp25a#b;Oe2ojja#pmUoF|#dr&8W-hPZ#rZfF!J@DLVkx!Vn%)K#giqbQ`G;LE> ldR%0)iYQ5Amu3}R{|RMS>3;1N)RF)I002ovPDHLkV1l&ZPDKC! literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/key_delete.png b/base/resources.pk3dir/gfx/icon16/key_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..00dec80d84e295960ce1dc1e67697a8069cb7a81 GIT binary patch literal 724 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 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/layers.png b/base/resources.pk3dir/gfx/icon16/layers.png new file mode 100644 index 0000000000000000000000000000000000000000..00818f63635ef3b3c04260c0d8f160b19570cb62 GIT binary patch literal 597 zcmV-b0;>IqP)62!*BTExOSjY%3)*jT5svJpGKf=$3CUqKK-1RDzx8ymlZ zwS;W;-7_=ySiHB1u9f68hg;0tAIzK-5q6bH&%Yeqk1(r}i84|~$mldU469wb{r=gf zuYVfkh}abCXHiD56XS1@m(?2&*9kHq6O|^j@r%)9WR;gBSR*+^{BUiAhv zLTNl5-SWcMf`$Z#q6Tzk02$5(j=VTsw!_ijI|?3O5Ws14CO8uvli9}fO~g1=Dv?Sg z6QM+>P3O~zsHL}l?cjL#8yuEVU~n|V*x($S*`2dri>5x}hU56pjd4M7=H5jVf&jnh_YoHFW1pQh33@EE+GcT-uHR1*sID5Hzvg z6g2}hp<@K+0FD7#ACek+3k!>iLhA`|uU)j;i__)Z&Fgb3t?v-b7s4*agaQ+5 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/layout.png b/base/resources.pk3dir/gfx/icon16/layout.png new file mode 100644 index 0000000000000000000000000000000000000000..ea086b0428b38a89060a9a375185955b46ef8a16 GIT binary patch literal 480 zcmV<60U!Q}P)bIK^Vv3-yA1LIIsp&s02Z_@K!5`#FX}eq)v)_0l`)ftgN*V#4liHAy(R@)k5$_ zz+fRLk_!vjJvlS)-*?c3MK>79^8`s8M#QZ=d~*vp16%_xfrJQ{sH#8}z|64B_Dt0J z`P0WPW8(JB3js+iKY0CE|LOkIcXC92S;ReA+hk1aZ*^gg4_~%hT%<6a;!6vI(h<04K{gA?%Sd&@y6=YWeinIdj=VUB~cY!neEQ@}0VeaXlS6Fk3nozGu) zn5I8Ji!4)AIGIuW7!!BH}EWfPj0kw!x&q?jF;~BwWO0 zvkjpC_R$R{_2*~VkEAVJq{#Mc>CUTjlCENQ+$@0%Sw@yX8JQsokiZ5|y~hPf9L7(i W;q(Z^C>$XG00001r;P) zZezzV10q@u{(~D3H{r}Lkl<_rHY2+rym24G3$cBt|B)I7p>=x@2E_E70t<%J@A>aj zyX(JK%`Pzi-qR0QF<5QQPJ{u`T_?bT4rSZ_H!r*R-=cUM+<@2bzoB550l^j95C%kb z90v;;=WY34xAek)y_`)b20VN7_5YfKEB}|wO!%MH=l?&k%j>^yc@dHe+Kz%X=%laz zU%KGzf9;gDCcszBu1x)Z;n}YL{kyaNhxhCLH_w*rfw-XU2;6{@`IrWP zY}|Nx!vBreCV|C!_N4yr-;)k9;5*oWh^9mTUl0tqi6&npJ$x10^Z5HznC|jkhtXU{*?AXX+vSK$&lqrKo z4P`-MYRWlh-uHXoo+plGVQMtjm29&SnPTept1G}>;1qBiY)nF?X%bBWNhny_l)Z3d z&-N3@T)lWSVVldhUf%V8y7}mh3o^f*rno=*oe{IP>4|aPep(t*WGZD`whRe#WKrpOeww^A5*|8>ZEI3iJG3d@;ddSaaQQiv*3SWXm^*Pk(vkYVP=SQ%7gX+6s4|5yBQ}3^T_6XQ zZDbP)D!Ze~6zXIkQ9PYpWTZE?jfD>%Y1@{Swk5itNez`{Q)G&e7J>b9cP_BngG&!t zi|rp2nJV;T^4jymwofAMkUFri0;>ZDmaq-jpk-+0DUxkA;uk8$FcGE_?o$8&002ov JPDHLkV1i%8-68-0 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/layout_delete.png b/base/resources.pk3dir/gfx/icon16/layout_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..4bd45f1316a102817972acb897d940ca07bfec05 GIT binary patch literal 608 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 haCz~0y|kxf_9 z7P?RnghHTc8{8O6Fq$7XVrokmFDpeg)ba9i^Ict4oBli zs@3ZIaU8!ZrF#hpPT01MWmy=8 zfu?DMVMwFVU~_YmX0z#abaYIXN~OnbK&4X2#Bsdfy6$PmaZpMjr9>&!F4Hs-La@HR zj^}x`o}Ql3QmOQ}0NCH(|HQWK)2{2HltKuBWm%+BDbndQsZc@9V8SX!;t zdr6YKBc(hOMbUVYBw8HDL7Jv5UDt2U&(DAQ^t^V|G@H#ArIcTrrg_n}Z7j>eFbp(J zBZ?xr-7Z^OTZCcgkBp4GS*=$87y_EjrjsPekDlk9b6ppu6jDl*Qo}M$6CnikdL7^Q z+Y=KLv(;+#kpSrT``2vSKIeHJN-2a8Se8X5lOdbUlF4L{QWAzC<#HL%^TrMi4!!{p z08tdZ>o^Wl%Ew;XV>2n`a1&kE0qFI5%+AizZnw_^7*7D>mSvHqDVnCClwvR#{72*H z7DUv#*uZg|pN9a`G(YKdI*rZE zO(rKNu`G)xV1y6=*tSivSftTt;QM}*%jMo5D$LEzrE6Jns9fAm)w(y44ZEO*R`j=YGq~RwN9t=U7Du(LZQIa)D%i7{Ms_^?>Bh)^|!H4 zou+^HHh*@@29y}9pzWU1ISBqa%I^7_XrU@6kymn%J zRTWQUG($J(?Wf#-qzx46OO5}T)l0>Xg7$;U`amlUbhV>k@nUW8*}w5FT1Ip!-berd N002ovPDHLkV1fnpdxHP~ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/lightbulb_off.png b/base/resources.pk3dir/gfx/icon16/lightbulb_off.png new file mode 100644 index 0000000000000000000000000000000000000000..468e1f378d6bb8d359d5b34a9bb4a74f02e345fd GIT binary patch literal 742 zcmVEU_)&yNS5zrlMt zd~En@*U(=YTJ^+n*cyeA5yh$;DLq|M;`->Nk?)uLjd#U2M~B-pmcH2JTDwxNizOwN zWnlnO9JA#6yq@wXSEJl)lG=0o^2pOV;Na2Wbc+$)&Sq8*G&ME?5XUiEYZ9#iu%slF za(Vu8lH8Q{*SuKUeecT1oCL7r>dEFzdZ2mrDxxUHwk>SS#c><}s$oc}RAy#wp6<>M zDJ~UTYQ@qe;0pm@s^CCVI!zSCn5Kykg4(}})i4CWaU4t`@bU$^y0%aYOP>KqfLfwj z9mk;(1PCGO=K~~KlOzdRYnF;WzVFlCmPM)9sRP1D%~yh8oh2ocul~TcZ3aK?zz`-i zG*LC+?yosYeu>Q543!|jFhp1f_)1*PPZx$h>h1)fzq5rKzf1t2ltM~LPe+Qe2URw2 z+`w-SAA{wN0|pWY#IuX(YKqnd%tAD;=+4T4KGBZ1em(Pa_G=2+U z0(eixb*B5%vBZC~*EB`y>5Dw3G%IrYiMYw_ob8+3I&8I{gTtVcWm_hjdwG1IUqOj;LqOOhhFZ;&h6W@ZNN;e zS-@@9nC?2_-2Iy9*}v=O3&XcojPi1w7&_#2^bW2k5mbUQekEZ1=JkcqpKi6j@0BY7 zq9B-V&wjAJueT4+^O$({9AT)%mAoqgKL4ca?71_i`WDN|RVv1{seZR_@buLm@9@9t YEzw9Q@w=YEy#N3J07*qoM6N<$g82+>ivR!s literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/lightning.png b/base/resources.pk3dir/gfx/icon16/lightning.png new file mode 100644 index 0000000000000000000000000000000000000000..9680afd12f8fadf5b83f827240978446af5962b6 GIT binary patch literal 634 zcmV-=0)_pFP)3kp_oQM4NsQ6$aEKj6mx0hg})10sT;E2V;K zUHNY7qG&TIJ`gc&M*EmdrgP_>>zSLTO=}7j2M*`nnfbo+_|8cvrSLzG(R^{I&fHg| z3Nfi70*Jk=pS3m4lD_qhO!oanz~FpWe?InrjDM6H7D@P(w+NOTuL0gfPQ>)8EiKPO>RV|@%G(EApK7|ni6$Or7s}#zN5D2fFuoW z?SUp(cysDe%D^FVRe!-fK+o2zXp zH&*H~_``&05AX{CqjQ9Pq)Pw`p&~+e-<5=lgjH9A;4MsYR*p|Xp3o{VtL6Q8vD&1u z_TBwgt>E(`Zp(h8_8f=r&cr~-uy!|BC|zGKq17aQeR}wL=f1PUhPjus5Lo&7j={xc zCLhQZ=E~bn;<}`gh7Bu?>ih@P+*yw5-^u2k8!el-HG?lt4o$V&*`tbh^4#JtCOgRB z@^-thiGaZ!P|20J4^o7;v)78_|FldDe9Z$i&;9^|y&bKi-n=y{JsccrzVF2T076QP UWao5~B>(^b07*qoM6N<$g7%3ha{vGU literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/lightning_add.png b/base/resources.pk3dir/gfx/icon16/lightning_add.png new file mode 100644 index 0000000000000000000000000000000000000000..dac3c9050cd1ec973e93370f917bca2f06fe420c GIT binary patch literal 746 zcmVR5;6} zQr}BcVHoxg@IIoOz{C_FkX>Oj)x$T^-or(4Io9&zA%s>3`~3neJ;|LkE5gf`w#IA;av{V4EB^<#! zB9FzGXNbCPfwSa+H6BHf#)#PK5HOXKbU9p~WGQh8yucGQ8oav^+(a%yW7!A{W{T3i-_H?PT9GgX0%t6b6(YvG zq>c)N#`6#y$-xRaAD($6fPXtRdwEB98b8;yhqu2^Q3`7 zkmJqYbtXWB*0u8ty9G#BGaV zK{OtC+@mjqTUP*k$1cC^?T#%4_tMd8d4-LuXQEjk*aS{?bW1STnFeyYZv8&<#_`)JidW z8<_=K;UmF(%&0xoDfK!!&HLVSPXE0+I8C$bz{h{ifA9DGuX7|J1pa3!=?87N=Dy(K zqA4mk2RK=_zPFItGyc7}Zm8rR0V20<^R}86VCIi(69z+c`4i%6zHo~Cm%#GiiJPjc z+y)A)Yn>3f0j}#1Nga0gImB1TO)?|0D?O-fGdgc~Za)YXov@+_eI0i986?AVh^_j- z8L!OjfhDl?@%VXrjz@*0f2t}U)ON1Ic^&`_+1t|JGN}q@kg0WGv z0h_~vSa8zJ;Hsx#nZvs##F&JRXNybQYTLfuOD@Qxo7; zb1kfuU+@D zT1Z*wnCp24V^Ky$O(PuMeTa>|#FuxkSa4#z&6ce(lts1Ta3iub3eDezK;P%Jaw0pY zdm(kSAZMl%r6q;3kVKo3N&eckf7t0NLpU&is5Z4iVtWzg0p|`cP=96f4cyoXnMKzs{AvK_${3I2JB+KxN0Ufu@$4=bzE&*^yIyyx1BT6wnTq{7MmcwQ@C bH~oJAm=C4+@afe?00000NkvXXu0mjf4;oKi literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/lightning_go.png b/base/resources.pk3dir/gfx/icon16/lightning_go.png new file mode 100644 index 0000000000000000000000000000000000000000..29039e6a8b40f6ed99cae87f21ea8bf7650f265b GIT binary patch literal 739 zcmV<90v!E`P)ZgH#N0snj1RZ=5O!&o^!gea_a6n@WA=tJm=FUBKRM1W*hOrV~>U9f`~wv z0Tu|Y=)%0J6Hoe^LggC>gr#M3MGJ%lAchdF!VuE253mxEF{r-t40G)#`jbf6HD_`WwU$M6V#vcM2*Q#qvS~OkA~o z2X+9Mdw=9?o+sdf%>_z*h8O~qfunFgSf^kugh83b=D^9J(VPUr{K(}ELQD!`%%7PJ z?Ct=T=ZB$^(QAR`p;x)CV4LkdROfK{`n>)VP_cHf(h#k|mIYVoX~ZK>M2OYH#R7NA zC|vQRGY(=1aUytrq|_-S?Jn~~ebu-#6>{G$ z;Iu>2K>%gc%R!i`>EriVc(@Y%d9-x~vXMRtlG+efgGAvu^>|a(&{& zi#?t96Q26xH5Wm`ASN&bGl?jQ3$~$m>`Ow7tFbhel@i4YmQkqm)z}W~Y{bXOcjySeo>2x3)2;HwxvuqoCi6>( zE1z8&OJ>Jv@7Yr}`zB9kxMNB&8m3!icqK{XA4Z;5)n(h+sJMkx;HE>i-atjR|2L6A V!PJ$`dXYaZs9=SbAto%g@>T~?_bH&lTUn@`uo|1bXE{eSR(AO)ESb=V4`uk}mK|39Px&03WLbv~pzk+s7D@lK^ zn+aB+sp)&Y_x-B3>;6ywU--WQNUr<8>TU0P-|L#1U&;A)67w(+> pDf@fM7q9#F25QXo3rUI;002ro52U44e~JJA002ovPDHLkV1l;_q@Mr) literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/link_add.png b/base/resources.pk3dir/gfx/icon16/link_add.png new file mode 100644 index 0000000000000000000000000000000000000000..00be352c5783c0f009db7286bb4ac86f306634db GIT binary patch literal 570 zcmV-A0>%A_P)O?!~#Vdl*A~_RMaJeHZc^62(la$ zXNk(f!J;Kx`k;bWQJvnEklKv4E*yUMoqNvtUEX^F0D`|j@Q(r{5=p1oY+msBe7DJD z5^lHq%4)R^@aW?E8gVou4QYP_h{fV|l}fb|4u?^%*HNq0P$(4O@pvv=E?2Qytv(Z1 zDwRMQ(vqhcAQFj2>~{NorBb;y7z}$#rSi>WG9eO)!0B{?dg5r7N~NwyOP=o=ta!a% zE*g!p8jYqyDwRIw^LdoZWfY4=WHK2LM>EopmORY>hGAw|mc5I|PN#3O*(?%?1Z*}N91cgL4{iEji;aEEtZ88I z%HD_Pm~b;dC=|BwEA}fCic6!>_++tII36#0y?%nn(Cp&Gi)U*JyQeW6UFQ%wFhd_= zFktBpwDhgV{lnb$$vU>rBA^N!nh-iRQgVr8yH8%}^ zZn9za?@#`2175f^8t6qZXKdU|Cq1|P4!%N`c|6eCU*|IMpHVxOJgs;lasU7T07*qo IM6N<$g1>>Oks2`oIPl8XEc) z7Z-oHdiCnNh=_=7-rnASQd3j^Pnt9-52PSJKmR|74-yB-uUN6-AxJ$)AIt?^O-)VT zCr_T74pjKb-rk;L@7}!}=gytu04X?h=n%)+wQD(m;%Y$oCm?ko^&ov<19WwDGt<-4 z-%p!1tt2QYXs4s2<1aTixBr2Gf&W1YfV4h{4-yB-gVcf4gYO zty=YV-MV%Er%#{$zp$_nY(Pat1(**K2g!rffz*TafelboQ)31?&%n#e>wZc~%9rfy z?C(JQGdw&z4x}IUyRt?v{0wJ6^R0W@A*Z8= z&I?WjSJx&^y7yBz?2M*SZ18QRLbAs(#0rsh%4F{kwbCf;j=k00000NkvXXu0mjf-HSTy literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/link_delete.png b/base/resources.pk3dir/gfx/icon16/link_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..f66e2974efabf02bc8537899e25594978da8eadf GIT binary patch literal 600 zcmV-e0;m0nP)PbXFR5;7s zQbA~vVHh@k7qp$ajUZx&gbqS_iCr|e_8-)LqL<%OF#5$(JDAmU3Z>uMWC-Hc^m(S-Bi9|X+pYImKESqKGXh#~-{uQ9t>n~cZ)~J`?O(xSR&-1X`?Ps8wINFhhwB(rt++ar#gb&GNvR^C~zm>~np74t45QQ4l*wv8+v6+o86(g*3M%S_5fp9@M!XJD7zzCD0++nw0<1$_~** zQs@V3kR!#AEgGBVrfuf78Z(%>=H@rs#?$wWE?sQUtrs46dEOr$UY?f*fc7t-{U-~m ztE=~RcXwac>-8C@(+Q16GbfYDDoN}o^903FHL8c|{bK=>$=u!4)YNY>nUG4QkVqup z_xqvMYQLz}>OedmU#GZWFbLP+Rm7eOF#TMQ@keY-*h<@J<>loU6bi+1G#bqa1Ojhk zW8S z`FuW%jg27?2*B-jL)lqDWTH0WI?f;+(O@edL_Q%ydh`mWo`?`0Y+D*N^XRl=WHdK7PZ^EItjpy} zdpsUE91h6ka@Y()WFjhT5h1M22tmxZVr8-yGmhG&kH&Ll+ef6+>AOhTWgHGCDHe-Y zdwO~Z5{0{Rrgiay^7n8%h`G!7@kxzoYu#$ZP;t7b54?Q`E>6Bt6t?mK5J?f%=i9JM zDw(#`=VJp^M~WKhVb@_%)Z2@R*Z1&kqy=lqR;0&o;IozWJ!Y&b`KuFMx9fqGS;QV( z!f@|FyuaT7zwXpR*id-;a3jFMu%@C#&gw_4uqA~^s6002ovPDHLkV1m3RKd%4) literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/link_error.png b/base/resources.pk3dir/gfx/icon16/link_error.png new file mode 100644 index 0000000000000000000000000000000000000000..ab694b1ac4d7f1b68677912cd1ec0f99018d0dcf GIT binary patch literal 698 zcmV;r0!96aP)8OAT^C6!q-hsL7qc;vnlp1n2-QX8u+%$OL$pGNEQCpFO@jD}SYymh zC~6e=WjY5HWgF#|xz8nyvQ6D!+wouYbj|`RMY{T^^4I*=!bqARrQn zz;3svtyXI^nM{^gE*6V{X_%IIY5=KJddzG#FD4R+f>x^?Q7V-`+S}XV^?G5kSm5qD zkMINS&kH(jXkcIL;VAliKD}D4-Yl2Pmw28>JRZkrG=#)cJ@TmlCLf*h zFb&f(PYocENG|I2`i0)!-j24mwr5REO%;Vg0gXn3TU{qGKh=lo@-!v_n(8oT^Dr&* z)ByE#sZ^?|o}QkC!NI|NFc^g2?}x)?!g$~$O7o9V`szkOc!KcVGnM0N)ko&30mNeQ zCfasGOH0d)PN!Qo8jVGh$yg5GQIF-4LnwW5AbNctD)}MAxn}g+51E<5Hw*OPik~~M@=5zUQfKKX zH;{>VG3Jt8-4O8hw%nMBx>3&hSF5k2PSX)&t2;>>K)yXhv`g|mV&AiST>x!wmgEGK z3p`45^bO_$YhoDHr4N{W*@x#=abR5lZ7&z=ZXl!1y@XaGv=Vu7t)7Ih>>|`ec*{=0 gckUpe%iBkP0k>nXO;Ji58vp+WKzZym|j?YHA+l_EP7bFIf1E~S2MKQq0 z$cW9y$ER!J#EJi3ym;~d?%lip4<0=Dzp=6LUUhZ#p_?~v{s4&`IdbGbNDW9WNDtfq zLqkKq;^N{DSFc`u7ZDM$&D-1iPikuF|4EZ3{jaR7{10M-#6WT@R;+jkQVY_9?1HYQ zrl#+cCr?iI_xIVNnQjsGCEAU$vcG=ad^ z*Y|pFZ}0n6t5&^Tw{G44{H3=4a~E0sPhVj2KWVPv|C;ro|5u%!_`hVe|9{s$iGP~f z8d`7z)YR0NfzCGY^76W$l9KWzJ3IS(_G0t@8_rGpzxM1Du*MaqC;XqVr{w>_<6ZwV zmb(2nZD;?j+sw#_Gk%kS{sn37+m-*nb4T|7)@^D38#X8YZ`zvvf5xHa|1k?}{;SqA z{KRQM^lZ)lD^E@Mzw|`!|Aoi8{?9ww0W>7*|MWvm|I?Ow{8y}HxGr7Ez=_j4b?z7aYu(NNH*UVw|7iys{wFPV`!8S1a8a_7ft{qJtliA`I)0(^fB9;LGeFI3 pB$Rr>${ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/lock.png b/base/resources.pk3dir/gfx/icon16/lock.png new file mode 100644 index 0000000000000000000000000000000000000000..2ebc4f6f9663e32cad77d67ef93ab8843dfea3c0 GIT binary patch literal 749 zcmVe|tv9>?g+k#9o0pTxd@;_sq{kwlU;^VvV*?BV8P@}BoaZTQUROpWV6|-M`|^n&)=+8tHo3*<<$NU zU`%V~ZF;?hBSYsjJ6%JzV}E(D{pOLqQklliUf9um_tGl-wty`y*p?eYNW56P>X@1s zZs7KrRZKtmV7Lqj^5Fgr7_`LjhdJK@ltF&O`j7?*NUM$KvmNGz)3WjM?V$vHlPT0AFyF?kLE<#HZabCSW3-oa*6;Z zrXD`Ulwd<^2glP%1Y1Kc1Ij%DU^=ME(jKf6APNlA$Uu;J4bVilQHSWX5uJ$9Zsp4M z0%!@LvyTxz=Z6stxlichODIY+yNGt%RM;m`>H4LOKLFs9Y%b5aUN|2|{0Zw|<_~i} fmXz*V19AKYaD# zqJ;$!L?LRd}e49w&t(~$j)WaBu0@9%c*o7Cy&!r|R_?)koZzV9A^F^1ALJUm>k z>-uF))7mI1DM0aqVnS8b!JeL;<rL6_6GkUAaFSyzVmv$^|CA@kw_qu$?)4DNfMk+r%@LUhi56*+}GEa@Z5ADr7_&ySe%yVMuuAZa>R&dhFhLUY|yB)Du3cf5wWt^UJH@SAv{y6^y!r3!*jPK9NF%|U4$$flqzeSn<%3|-B_Ru=%13nc{9B6NO} zjGv)5q;nk{P3=fL9VC1WHg)*%WHN^Frs(C$?Nu9cAlhtC5?qmKw=Y&mrvUEPQAJ(WZm`O>-V zqM`fJ!CUawH1n;sC_$0Q1Dy=w9)w`Bucsq2QZiFsrP)|OXnq{;=f`lxe+O5eorcw9 z;n4gl0heH@Jqz1r69luR_=F<8gs$P_*9~|v^&IWZ`|x=BCd~BuW5H1lygsnSYr-p8LY@h*(vx=xS@d5|3BLf^$(>I_TlFFU0000F?<1APhrPm6@3t=I7^Y-uqpp zyJtoLmzlB>Ksqs;7m*vqVzEDpBBrOOsnu$T2xi7Wx^eZ$)Yx5M190O1xfOtj40m^T zZ+FfyJ3ITvdw*C&{t*#=y?1fAtG+M}yaG05rfm5;fcJi1E|+6&ZVu<%iII_!w*bwf z!ExXcaP`X2_~m>)e|zElc^exWJGdIKJ`6*u)hgcmzZ0H50KZ?@d-hhayxi>U?4(|= zKl(=EyZe9G!?{5|e##;uoc!@IDRY>3%*XAVaP8S1RF#cwiyYtln8DLegE)a1zx;fN zfRG@SCEyrn0O>ZsKpf($oExfvIsjf@fAH0Ti3be7@E7UKI)We%+5*`Em_q#%vh<3m z@d5R9vi&1i)Jy=p2Q`q0O8E(4xQ4>c{k*?3j_C$^4-8RxSte>M(%#pFnP4tT0vwoO z;wTL6AZ%R+fg(-e`9hXnA_~QRKG!msuY>6dAOtYyFcT2R;)`cg%8wxQ=x3$bXo5vl zW~QmkzKhpY#hgnda4x1wL}8$hRPF}|BewnaC)=EdrH^zLduUy1i4&-;21KBW`iM%o zOe)t7ZFxwyf_hl0&{+HzSF6(A+kv6++DU+!klAvI?A8=PYbJieumw~gYS7-OBCd(4 z#J;>w0HP*uZjQz-yvMxz(thPcB>q?;@m&Rg{{XvsrAoLsMFs!>002ovPDHLkV1mrW BXp#T` literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/lock_delete.png b/base/resources.pk3dir/gfx/icon16/lock_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..ecb50a93fd53c590b260ce9bbf88341386f7b0cf GIT binary patch literal 815 zcmV+~1JL}5P)5&PNmf`5mIF?X(>Nr_OzAky>%LC^xjHsh2Y&83|M~y#eBXD@6&Pcv9797xHKu7^ zH4LMjVgm&zeo~C-x<1g;)AOscUZ?~Jg+e>2`EEl)gWv6TLli~O8pUD}sZnrfJSVp4c1)t9s z&@>IvXmlo<%_=mv@!<2Rsi`>*OzZ+AC0Op0%M(hryId~BVlhzD(O@u`sF0fI@9*zO zBoYxtQLNhk0n~HNbQ+(>@z>xv&W_g*+xj&g%)UCq#$v6Q&p0j3$J)jrF%8Vn!SvN{fuF<+_4FOc_Bsec4HZ@aP7kF`AfJJ;^aX0+8%#Y9r#}d$mMQ>Y|L@r?0{8Z$n|?5h5=~G1^ge$$AHj+-1zLv@U!O6N`8BLUfo#6Qx24@sY;} z9O#B4_6)+{Nw{Y2L20T56WC?B48XNAlHl2@KyuX*fQsf*=h3X`cyeMGj!k~x@RikT zm9P6CnS!zcpppkB8N@x9B!G2*gN&4Il-D7-?Z}58qWZx_V)Pw(>d7uiFeJ>a0&ofT z#aB_TViqb@}g8~$BiXmB+@3yzMZ{VN7WC4D^zmAgoT`rf$ZnuMFS=o7-ne@ z=zLdKSKvPYCEIB8v)Ajb5=9ZwXcRop>!*X`I5?e7XDfBVd{17oh+bK*PKiy_4nC-jk;Xt zueW*fk~5~DKa!!CX?1tRMiZ} zo>R!oKY_5qVCh>5Qd(R|3mZo{kck&B90vmyjLAatX+UMjooz_PhLK4G;PAF0J@*J~ zzKlFu1yQha_(W5=5ir=J99ke8o=Gnas2Yy`-|!W=1KRFoY&N68Pt=E)G(Jy;nW zMVep2;f_h8ovdCaRJsd_h{VJw62TEHL?*Es&!DWP72-lKO!*oz>lKI%e1h}jHK57nhq2wufGe;=lf)bV^ltWZi);*ZOL}(uO9zQ_izDih2&1l;1BOiW3;*%(J zQ~4yykev(AC75^LfTh9&e~Z~@A=yq~k|qjJgd{16#M}AB@4vbhi=h?^Ed(L}K&wJD|>xJihJn!@Tp5O2HzLI5G*jhtFLq5|q zdpPGE6hR75tWt~{hVihwyE~5^OWFb$92{(==8@{^>O+3N9}b5D^bbwbkjZ4QM2mnf z_4f8o{{ukHKHB_LS65fh7(+UpMxjs;(;>?;!r`!8oJ=McDAy8?$4grP4)LJm?MNh2 zuj@MI=H?bvRgKcOON98Iot<3~z{IYeq{Ox}ki~4dlrZm5*%LAIDh ze^&wvPv8BKASQ`IhAmtV7%euqo82;HJ7LTmQ(G@Ncf0xg}; z3}!bgKj)#F1_A2Osb;;bqILgCmM>%|B_gF*g;{RgO- z+hE^v%Lw|aFqIy|SZeeOSxe3ofCnT5KKEmO4ItiK#(#uOKPCdB_$>BjJ`xS|T6UQF$ z^2RB!G8RXAV0&R-9DOs4-*38M$U9ZMTziF)0^Jw^yt#e>9x2Gxz6Fgs00000NkvXX Hu0mjf94>kU literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/lock_open.png b/base/resources.pk3dir/gfx/icon16/lock_open.png new file mode 100644 index 0000000000000000000000000000000000000000..a471765ff1432092e7113e56b42f2798968b443f GIT binary patch literal 727 zcmV;|0x127P)rLKlJyH=-*k3W|aiVYC~e{STzB+=%NyKm^5w z3m4+bm8cXnzG}0Gw2c^Ol0K$0_ity0#@^}dhsl97GUJu9lkxh`Okt_0|=(|h`!tol*)tahk*i! zgS8GLCq{|Gd7N1T=a4u`0gM4BU}M^~w|L$b3WtyL{rO$Q?PPfL6z$J7;&2In&vryC zqT@6`g9u_Zg@Xt1vO7RIY-D-g8eo{1!oIz%ujUZ52IBq#JOI%e5ertc^kIf}?KOA? zx9*6-2qdQcN5WDRs@&WP6I?Nxm{No*quRTbIBKa{opLb zA%3`w)e+)sGB0CNfHFvOi&e6QxioJs_E&O>(i(H5HPdeu45xa7-3Gh;%9Wh4nr0hffOdNC-?LD$p>QUytZsFT-LsVDm- zkkSuK6Kx&cjl{J`-nH0(5h`dBM1#Fu?T7^`3P5)5#Nmi=+?@y~3iOBukAMi~N&`d$ z;nBbdW?w(fN{^ns%ib@_e0kqddisx3UCQcxgClhAKEkK3ZBvskK4+6J=duqo6B*0Z z`QiTU4DIirW#!`(Ko${HDwSbi45$P5fJ;R`n&p9uvCp3Qf^#rZhr`|b(6_bjBcSYSnl@17o0 z)pF+)RYBDvVi7U3XstoS#P(n4-TRk-s+O?SZ#U-- z)uGNa_H`=zYUj&~Kt|x~lMf81CQ;)Mqo`42MrV0VSw3O~Bc64YMQmPO#FhK~#Q+g& zXE?Du&d;pTaAb>yqyOehmQ`|mY#Y(V0i&PCsjeu(8q2JJvj#Qku+h#oIx!g|#bS-c ziX%BTMcU{e0b{07G2|4MWE_{!c_(24iWf`S(m^_V9x;_3r|*R!TCfs0LU3^RChxt& zIfwTSAENUNhk1oQi}g9Zn{Y$;-|Kn4Z@$Iqxp_zk5y&5xNH2$q6FF-#i1j9?bWg>zm73!<7nwNua&|TB_w2 XJTQQHJy`Yt00000NkvXXu0mjf949vz literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/lorry_delete.png b/base/resources.pk3dir/gfx/icon16/lorry_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..66217f52624e760da3f2d580396f1c90a259cb66 GIT binary patch literal 683 zcmV;c0#yBpP)%;e;!*Jc25-JmCI%BTIqI9dck*$7$fCUN^nZ8d@iAQQ zX#k5NvAFI%c=`S=fDFO4kr~92YhWuN%V5i(G-vU_sv?jhSW?u7f;buu;{Nk@r2r6c zE{)#Zli0|a^(8y7FZ~ZLEDPa6q7fwp2D1yxI8YOWvkqATaTaV-{-Dba3fYX2 zBf*!%I#QOm2&~-%lSOWEdB$<_ofq;iz)*5Hw)PtC_Em(FaoExdw5FQ?oP#-Y{D`Uw zLb(R&&?ca>q35f9OhXM3TIwnUu_xGXn(-J(%EPua zT=d_40N{xU=U0S*6PLF>(2YuXVrtEH!W3x_%(Zl%uPOR5f^=#D8vxc;J;dUe-&U9k zOUs8ozn!3;n*~_)c42wRV0zxL0uRl0;~eeYd*#!eLm_g8C7!sOgbzQEt?#Ao=_5Tn^=QTAA5Q0H44#5pbGC^d5$hc_@ z1iISyrOiM_;pCM388t6*xtEU8Qgn%oEH_%6H*x=JA6=nL4a!wF&J5f-&}Nq@=9M-5 zw^r8Qiz`Pf!MH#qHgCJzIdX%JQv{b^P9PMW1JgJRjUo_?B(wI1%D&=a`4H_(u&JmJ z6-6%GelobqEJ4?kIK6rRadm1bWt~#gtn>xfk?j_66*nR}+l{GdFG|MElT&lkSRhfh{ zHwWz33*>J;hWMvf_->SdL`)I156nQkX{An33x#aslBIdL&W-&?&H;-740k+7^{Gox zV?%h{5rjHvC-)OjpZ0uEK1TJhYeO~GZrO`aOi8S-Y{0hdm8hxN4W}y(o(zMS!RFtg zxb^~?s}_)@eR=)oQ$FtZ```L}zFu0N?Cb3r+*vR^ms3~{9v>y&1ggBH;93+8$2dGY zyl8347?qAny3Z77t38|RIe0IBVJK^*fBipOW+}dn1u@=r?U_B@t22_CBk;hR5cKLyQ7s6|!W3KN{|4Nj Vo8&VeC8+=a002ovPDHLkV1kBFM!o<5 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/lorry_flatbed.png b/base/resources.pk3dir/gfx/icon16/lorry_flatbed.png new file mode 100644 index 0000000000000000000000000000000000000000..8b20f55034322d068b664b01e5a99098b64f5541 GIT binary patch literal 450 zcmV;z0X_bSP)|Gy8kTQ_kj z#DMGb3pZSzo%8?PwABA6CdB+d)D`@HSCi-e&DHk**OZw2Uy`Hse_om*$jSeY-gx_e z_MV6T_g{JaUn6<}!~l@yXXjVL@uQOq|KHs|`TxzWt^cpCuYqHblMh^Z^MCK9*Z+52 zeDz-?Y!1YLcwgK9vEEkyqdm?4N4lB(4|6g2AL69@KgeG5e}Jvpe?M#G|2~$A|Fx`x z{%cwV{@1Vw_^)p6|6k3_4-p2Mnws}gQd0isE4dEz%xDk41~1Rl9;{Q|l4}F|eS8iylz4ix#b- z2uqU?YoWCXGkb`pw@3`F?Edff&CJ*0s+)=e2ZqC$#o^2uCJG@im&#&}mD7Lg^oXjK znklM+sz<~l;%3o%hlp!C(A2s2Hvv^GE!?(`5R{-sFu_a-Dg^bI3PFVz_ipa_qXQ9- znUJ1L5>znpnEDKg!^E**@p7)^wQ%M9lc1ugsEU`9U6=M>&k=DHRUiE4uG-l_WV+R*P#2>v#(a#4 zCl<$wf+|`&chd82bXFk8xfm74{Jf$};*v@J>bEvRw#S*^Ci*GOUrklQ$TRAAyBfB<)5DYUT1S3pi>G1@+YmTA8P*aS+=gAQg3k!Mn;W52KPl+|XB{bNz8ymlY4I5ZeT<8K)pAK?919}}r@hQ7XM!^$13DXAltFdl^vsIIQw z4zvI%;0AE2_6%DOtv`X7BBp3CK1~jjzo?j(AG>+<`r%inG(>-Uro&e&EOriOj#wO( z1vSx@iaqoUchf%5_Sp#y$>z`({qHxfYs#9cE341#9B3bPMnkeWyaD)cfr`dxN-aA# hWm@s2ISkIse*qhAp}qdd4(I>?002ovPDHLkV1g_sL3#iH literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/lorry_link.png b/base/resources.pk3dir/gfx/icon16/lorry_link.png new file mode 100644 index 0000000000000000000000000000000000000000..5e6663e5c4abc40cc076fe45ee627e332d8e4412 GIT binary patch literal 775 zcmV+i1Ni)jP) zss$BMK`ojTfnEp>@j@`Sskt1w&-de;({q-MqM!?3czDip&iQ>j=RHReLSQFf4R-jc z^N+418Do1nXJE{vFkqT8^lCN?Io98tycs+37l8z~gd-4wK`;)%O-M39WP-?eC7YOe zK6(6~4x|bvkhYnwY~-?*K$%HhhSl!HMB{BdxbdF0kW-Vq8s_Er-TsHFwCD*A{I^#Y zdxvZ14uNrj}_2nYw(>XAm!_-NE!qix`-tV)46rq~}2mKCowL5U{ z@n>hH1;fyA(H%#zW@+29K^FC@eOd2n_G2V@81@DQORHG~S{*QS162Y}r_A)yHqfX7 zWft4#ApwTTkx1rIB3D%cT`yOFb&a0NiI+=dB$o0>6&vAd@nSW-h$EH~6up4hvq^Yc zn(<|31Ffoto}M0?IvM{4@o|Fw1P2!!tj>XB{bw+A;VcS;0+Pvnc>U@Hx@xC!YG4=* z_4Qa;SwX#Z8gIYbuPgE@2ZO=Ia5&svEEeH*yT$q8Vdc))7`C>ygwN+wLZMIvl*wd} zPN!kF+c7#iifA;t`RghVO-)UGnwy*Z>U26yIWaps`yrptmj(w1(cRsRNF;*3zCPq~ zIVRWSo~EWIt11VHL?TYr^UL zR(^kt)XIU5j*h3jy}f(d+S<6Ps?N2wH7qPFz-qO^@At#w@zA?4HK_Ee zZ1H-%AySM|?`{HF?yH002ovPDHLk FV1k}6a9;ob literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/magnifier.png b/base/resources.pk3dir/gfx/icon16/magnifier.png new file mode 100644 index 0000000000000000000000000000000000000000..cf3d97f75e9cde9c143980d89272fe61fc2d64ee GIT binary patch literal 615 zcmV-t0+{`YP)gNuvOO$0ks zMIj=HnnBRUR?tKXG11rxCU4&7dG4NbuvR2_mEvc)n?Cow;~Wve|KR^>9@p5l)|QB+ z$jmun3q#x>;ss-PW_mnr2MHVzLAl1RW&0?VkixF*4t!St0YVb2wnKdU(kmOHiL;aW zK8Xte%(k>MVGG$E4no6dcNnb>BhVHHGD&1pv4YZ68kE2V03t5#PCEFm7=ad$6)+3B zTCmn*?A?=u(o~ET7~-7g0)ZB=6|lumi4}B}MLgy~Ysy6)Q5%Al7|05&1z3Jpu>cF8 z3?VXs*3<}%h3`5Wld)N2zJnk%Agw<~3k)sPTLFd=F5;d8-bj-09SkQuynfflNcZLN z!^_37fdZvzrq=9~mp*($%mcDRKC&qvaaZuX+C=AT6O*~tHl>0mcP<_q>-z%$xO(@! zYluq5a8VQI$S@4?r*v;gPo!QQ%pX3A#>xx4t=w-L6COWx?aj&`f+!YePsFtj=hOQR zP3=E2j@9L7s8;T^&s?u(Hdpu?CubjMrGn{t_37>9$|AD)QE08weJlKn8|OyjL~7oP zC8mPT`jzuH*Dh^I0048RGafUIT)4H~*m8m>egI0iH=(LB%b@@O002ovPDHLkV1lw0 B3FJNMp+(Bt!=q9U!ZZOlw$c zuAy5i+nTd|<_>NivLu&tYWf+obh7aHN%Hi45`pBR)x`tA#^U98gM4FFC6h~&)aWQw>e5Y84Gj%C?Fa5wL3#v12nvm3<6OafjJt}U((Qj zn8!nMmXr-qoCO7XcZRS8(x9RlIA>F^1(GoPldw}sc)rpQ>IL9yYf!7MN);5mno3dL zFr9-f3^@5I0h2d@QBNW#I`RB4IwvonO1T#W1?;?jrZNjp_!1ar;E|a)8g&BH^;Scq zt%uAgf}pb+yKn5ouFDnCJb}hGpY=s(m>77B`PIn4hUqw48S;@<+#YViwZYT4_>vEC z?=frJc<3Fn+HA3jXTwUklhgJ-dYkmNL^YBTW!uzZM O00008VI0S0!CoiyA}k0DS`b78y(oGU6a>AkUK9~n*^7|=kr7cwRFWv6%Z}9bXJxHq zv!bQ7t!|lawm;5>vpILy?iOC&HfG!Hc8BBJ-HKqfMb?WCJa0aq=l6SfssL2|4?ho1 zYF_hZS|)5^i5(2(3eSVtLjTwt+viCU4@P*+9|NQ!zmCYHkC8wnWH2cSOj5$smpmL3 zY1}4f$SympsTgoXWWvkj!KP${W<>az96Yfc0&EV^Sqav$1oSUxqGI6Xq{vddRFu7n z`2LdsHzi;=Dtr$y0$QI$*opyl-1%;k%_tFkSWDaJm;MHp-}I<6Z; z`=uSavTxAsh-+>P#z@O32VYD;@Uw_<1$Q)qo>w&5O)gAWuE2V33*Ucwqps{ny7nxp zX|aTf%a1~AQ*W?v_D-PC*yD@0=#7-ucnX}S5B~d&FdbXR-#fBe_gkP615I1CPtR;N z4-*FwcN*ZjSr5aZ75rZZR34vLukCGEW45>LLezQ{#QvpNP(bBYeXX{uZkgF|xEA`o r)y)eIsC4dIvZ!Ov;+nFL_^*5eZM*&99v4+f|_@RWw>5)RM`NuV&uI^xiO$D8`6BxXk0tJ?EWs<_-8>2;-) zWKcp3o`T%Jbv8DZ00H?+2@8dyT21gt$m6G*2l$?iC6Iztstut4r2wd-3P8bM5!|^x z6MJ9rp47dzLZAW(K~IDt2)_Q5!O~ibDk+Onsseb-MV?(yFmrC!xqLisbKh@i`-x=iJSj(h!<$+YCJC zMh+7C(a}Ik*keF=COGS#EATV${Oe*7f!k~yXly>8nc$8|D~`n~7tbU)p80iOW6x*> zfhd3a=HED-HQ7{p(#WSK4HSf6DS~k8V+{yoc_aZyUS8kc%l3kxbZR=z9LMhG;Wrw3 z8^CWiKHr1Xmw!h<2Y=(jgSQm?7a{$E6f%b+jDrMKM)1nw&G3%||GEwVKPFC*l;udx P00000NkvXXu0mjfxkDO? literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/map.png b/base/resources.pk3dir/gfx/icon16/map.png new file mode 100644 index 0000000000000000000000000000000000000000..f90ef25ec7f1cb0fdae38d9fe2d9edeee9928ef1 GIT binary patch literal 804 zcmV+<1Ka$GP)mbpQb1@7I~O+ue5CWtZi#AZox@gcwb{Xkx^Rf;Ty8yn6DWhJV4kC*wg94<7Vt zlteKm5+jKLV^qM1yt2HO4YZw^&a^Wfzb_m+@y40e_0^+M6ajz$03Zl}fU=sqfA9W} z@#^~O(a%3QB{YI^J_A4y)M^1_vjjn1H`Mc5t@6>y50A!C6seTL>`UqQ7p$DgY@K|> zQm^as;HM{#Qwj<3}(>R-AM4&+cd0t49%y2X`UaCBJg8YmB)K#uA{Z>9n zOp8>WCg#&r06`o8oz6gaIn`fY2FR)ssCr@3rc|5f%`bIJO$zbt__PK3gH51Sff`H}0ZWac9&q~*( zO@qNscV0VSU%X#sYO9)Qx4M=(eR(m}UFhondELHSnO2hr&mMO3 zv6gmw!P2y#u0c!?LPO88NyxOTj>XWm>*77F&55fo9Z?)iynObdfA;SdwVRl$W~G3* zEGt!2+1T-%ja32&!XdoMS_mM#IQK#{6D_nvjYu`GlvO3XdE)qYJJ;7%4Eq2Gf?M=uT9%H^ z8mm>^ym`Tm?6?O@iCV4h@k*i;m#t2+H|C_oG_K0ZUyH!)t9 zyt~8Xrz-|8Z%~=;n(eJ9SD&=DQc@l%Yqok=B@hunr_+_CEy-%4IhOnPSvp_*rN}#? z-f5k7s@KhQvedAb2_T3AV03gswVoNT*FpKMEk-{$FV3H`v2jgjv~5%Mipt26Ui+?6 z^tOOF0GdfAO}ohay70)oeq{YKx#v#Yv~V!Xh2@6AiwZM}BW3p*+TVj&2qPds6D z&~>@ha<^ADH96(czF^dCwVE49N@+h}!!>jVp_u}(=ED!IB0$PL2Qr=e?sTvy{x27_t zx~6K&d}8zc1xwkAa;SP^`+MNXzT=*r*{LuT5rhz_sjG&XNnj=^34AL7flM9_nKD# O0000rXG#NL7kjUIN;Xf(FQ!U7F;#?Ic#SV*+6vCtSr zB4QNKU_yitIYM&0)PsZLfW4iWo!Q;F@%zI3(O1sQ%*`CER;vIY000OAAYfRmd-&kt zFVW20%)!q;IU!Vn;rajoK~O3MkPc!5Wm!?Kmr8~AkH2>?s#dECLt*fhlksHmlF(cJx=(n%j-lt7;=P-L#K20u=(tvRo3UI%^%>@xtT1WMAG?7MV)_ zq^uX~=ZP$dt@jfF1W^Dq8k3r>M7z}jwKsNZ96K*6p0Z`;s;tqowRuH-WJSMsTeb40 zfG7aEokSexNL*Z6_RpYVWchn(3)&%ZGwPCx`Bwy=Sy@-~QJ>P~Y{O-j$y$oIhjtlcoxkW$DjUSh9EwYSUC5sZBq?VwWhl=bbF<0 zadMyV>e0hLZkU^Wxmt@51V8`)JfGaM{q98*St1@Cv)JD2>~Pbm{{g6=P22q_L-GIs N002ovPDHLkV1gmUl12ak literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/map_edit.png b/base/resources.pk3dir/gfx/icon16/map_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..93d4d7e5ff6c719515b90f39169103a252592951 GIT binary patch literal 876 zcmV-y1C#uTP)<~|mI`fywX|v|Ht`@Blg5Km<3)}{Z-f&EHT($e=$1y4^7g5>CQYRjDG3sv zr}oVZU6(`3r}omBbGUo=I&-x%+%Nm&axM=yeUxcYsYSeTL}Qr>gB`xVi9c#n2?D}P zw+VtZf*?Q|Gc@W|>S2{;J)m9>NTM1dEkH1ZZJt*I9kc6XH@x!;nb&$K_3b7bFHld0 z$>np{%D}X2f-pj)0SG4l5PaV!2&z!Z5_KgwpUuN_Ep&L5xN(@UYEW!m;Xvgg%6XdF zg)8iLJ22Vdc_q*>dC$c^F-F(>n= zXp5o-wID=9Q|(MqPe62T5&e3BeEkf=eZx5YhuB(}!L*Y zZPu|tvTt5PRTZPXLwG|k(pdWxdzbLX>>ZMp;*+@;L)cdJYXm_9zf$9;)d!qkSmNfv zEwZMIw{ME*{s)Nl2+PUQ5iVm-Oi_sy1|kUH=6j(d&uo~m+_WfGA2D`l9Pja0iB{jk zuwt5(LCW7vbI&MZ6bEQC`J2|7>6ImBR`1|AIjnp0j5vdoo}8lj;6s$HiTnZ9zrVqc z`$j2ub}(gUXfp)}lN#kTCSyC;iz|$0M@U*F)^5E^SIH*Y+QY{6pSkhW1lsGOv)KTx zX){0&G05TKNDga$nX$vi$*f%C_X|HT`}Gz#zq*RMxEsUl#KywLB8?LSFq0%DO;h^2 z$LTM?=O3M;`P-Ka9e5tUyvfR~dG?t&}89kynmRT`ZP*UQ(6` z2$k6{7#}S1?C2onmN30uAk-P!gdGA&l2U$HzVsJ$Njv@DAMu|600000;GBGqrEGw;Tan07PX6DVCH*elYzhBsU=<(Atb2GcE)hYl8004pj2*~on z?Z0oIsm;vI?0)<8cZ5oi6(axyL8%l#Jcc44urK8oFbZfPvTC3~!6G!%z>b0s0K&P{+vu#W_io~a`h@zXK zC=!O33<^$5v$zuQxtBw2-c%}R$1S$lOBt!iu*6DWiCUXC7B{^|j znI|ggXHNdO-trP-k0nqF8MbQv_-{1JlsVf(hkEGJ?evxLG4bxj~o4;Q#>3iv`_q_Jh zegQQh2$-Cj*Ug50h+}`Gby<;mbo&u`S;&iAp|sptvSZT&qIBTd5BAs*o>qghES+Ea z-K85pYc^YwB#~sPyeurP{%TZYvSMVEk93DUJ2yWl8pX~I-c<{Tv%ZylWPGe?qS2NN zQ%RP{^2{BR3$h}YmxY_1KTS91U0nLc<>f2x?H*7g2%(~7(jdgf^M*B{Db5nd&%Gio zQc0G&dv?2BcRl99;@8eEp7ZL#6Fxrnsalrh@;tY3dZ&#u1Q6`n@+1f$fWyb`6Dkdt zmoIzc@P{@|Ey(gugnfse_OahVzBqrvaduZl%W_EUGX2~lqZrjZY@1Ab7<46l2Np>VpckHIA{JYE2^no-@h1mtO>BKaj zm`_vFX{stRAuJHY0Wch{(UkVSzrsg<>b|vV{ooUp${VKDG5t|rCu)h?9cf+&VTPau z1WA%e(}~CHwcUM{>DSk(7n=OMa+b;`nR1q!6`A=g7eWJKfZ=eRrZgH3B=0?A-zPh& zmk;W$&K#NVX!j1=+l{n4ZIgVCT>>!y6va%I=0a#pmTS>*reFN+r<12mn}y>3Rh>8% zRf+D>svt%X2f)(ONNYMIlWy-6$w#rLqpHMFW~Z zF)cKmF^B{5DzjCWx}BcorJ-Ur*W1&RB^N#1JZLl?D@Ec~@ZjH4oZWHv_sbwA2%)8K zU>b7Wddc3?a;~zhsFdD zgkyM>qalEm$--vTa`)1X?Q6d|a{PJE-u*^+^UNFHuC1@W7PVsp0T2KH5CEP0fs-q> bqL}#~;%Pj^C=){W00000NkvXXu0mjfH4Ss< literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/medal_bronze_1.png b/base/resources.pk3dir/gfx/icon16/medal_bronze_1.png new file mode 100644 index 0000000000000000000000000000000000000000..5f8a6d65d5b04eb7c08704bc3e13e4aa58d8236f GIT binary patch literal 640 zcmV-`0)PF9P)`P1v}r1H+ja=6UDkoHNeMI34Nf6XW_#WMcyp!BRqF zM29h3TEaejqW$r`J7sE&j8Vu&Kou$XB3Ou{$X^0cFcH*yRHPIVIa}8z2vp7qgot?$ zb8{r`QSV9KlZpa2Kab`EEQJ3!2yxXN?yWR#^=aL$L#;YIcSv3kKJSu3T>Ym&{r>&| zQt8JV4=?!oEGbnmDR7dL4fbhP-uB(SbTG=e(<<1TJGa5T3k%O@d}yHgFQhoZVu48j zSEbQ(OnrUXCEA1R+3xoF93<(;wMR2vTBN*33MFVUphb@Kev%*cC}x*u^f-0Kl4vT6 zv3&&{9G9R3kcdW)NkHQO`F+ShrogAg@f@g4t5vaBpc1eYQ7PdRh9bToc|nt#o=`?B zn@HlB^|P6VQ394crW5+W)Q(*2gQoM=#g}=A9#9Yuk)v@3DQ?z!d$?MLrf|-B`EsI? zwP^YuNMLi^!9dq)JFmN$%c*2dP{mUDCorShYSU)G0+SKqfs a@BaZ*f3CHDs;P1S0000gn_Py*^3f)*N7*a%wSf-Fz>>todNGT#B=>)M`EK;mZ{((hAK@ludS}2Hw zNSYLa2#Jj$$oi4RO*U`e%>A->o4D&H7Y>(U?m2TfbDf#txbDBZYd5Z3$5v+pVhT|i zK*7qmdZB^mYcKHT;d^(?i7`}647Ge%RKTi({tqGWFy%jiz%T$^ys}?={qOs|c<%NjP0!#+A{b|IoMO7ai(5OddrPx!Z`UzyvIl#oj^prg?wT`16pfYNmeVzk(01B`N2%T{ULhEt& z3tXH)C5%|lUlv43872P%9I!s_psy?O*0XlvQbb7!P=yJ>hyXJb%2gDr3F1#1ZPRFF zY!3h+JifdHMk~xO*0YI=5LTE^0ZK7(w2OFaqpj?g&#msPo+b%707*qoM6N<$g0NH=B>(^b literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/medal_bronze_3.png b/base/resources.pk3dir/gfx/icon16/medal_bronze_3.png new file mode 100644 index 0000000000000000000000000000000000000000..ed3f43eb02ed2a663bc7e7d90ee1db42d66809b8 GIT binary patch literal 646 zcmV;10(t$3P)tEd$*D0XNa#H~{u@&`DHPzMJWk%F7xR2(`~hfa=lsOTVF#lJyH zOHm36RcKx8VuTuuO>XYJ-}&K?wj?Ha;Bc1jdC$xHoygreuA9%^`~6#2+5FzX#8EX= z4O2tJs7;?|Wo?^}D|ez}rbthjDrSy^BT%|irQ0HoiuNM?0w>#ocA*~lMDQPhLZ1Us z+DYKj=`tbLzP@s%LMzEo{jUREI{5No@!o|^E|&KgwKf2WSNOpcuXkoJDK7OgQE!O8 zR+~?>{5-yX_f#lNqFTTuC6a`=vroSJwlz-jxcKnX>VSa1xiJgTyL{$JHOtFb@*7Fp zct~-{AsV4P8Zox}qE7JJ@uQus{tQ$W?e}5KIouh%f;#G_z_YrsPQcSb7Xl*eO=pEv4mh2^1#ls~;X zkFb=_%vICUWmF8$5(o*U_CCe!jk-y+cy@Jfb*KP9x-dO!Embb5TU#BEo3hLTZ;4)MjYmq6dlVGHB7JO-msN z%Iqno2vOD`2re>_p`5{)x!%`#bpc5{(Fd&5_<9L0}=-hfsKtp zG6u;x1f>wAZ1(m-zIl&|@mB0pZ&ET3uh0fe{L0VfOY)AF@|54!6J0vqV7&&esb|S34l$G`gnC-%!Nr9`L zT?xYH7MH+67VWrH>4lrXc}QJBoz85S&LX0r=N9SaOWO&Eo`QUq=u+jVf9!Uh=SP&> zRWNr=`Qj=PC7YBX5+x{~f1C!DeddkS^i~fzOR~1hbsmd>+c_n*2$a-^aBZ;M3hZnS zZqvm&QQ*lPCQ8A2XvKaAr%(jyQ<)ka^@3VZ2P~g~!^#1V_w4jQ$heSYfn=cxxSo3v z%>82i?By`CoJKz0QB$~oI=^aVhhIMUcCTcjEdE4{Zb;t+*#NloYy;?GnP8hj4 z5W`d){ub#v{#Yw8NhQv=UkloAoq2+my+?EzEh=!tkn!bd+9WnYW>hH=fe-o(K#e)C z3`{LgVrZ;CAQ*bxkA>f}x^x2q(4o$OSW_gizPutkB}q|t_6^+V3@d4#S6cP=u>S~Dhet_ drXDUQ{{mj?xUREc-`xNJ002ovPDHLkV1i_JQQZIl literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/medal_bronze_delete.png b/base/resources.pk3dir/gfx/icon16/medal_bronze_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..d32aed727a274c60dbba1060637b25791ddd2ae3 GIT binary patch literal 730 zcmV<00ww*4P)W2cRU zi9*0MK@d@5KvX0|iTTn?&iCHko!zl`lS`uLz%sK7zlYxpJ4RIj2$wD@yZ0hPL#PNE z0?~WoQZ5}ojy@k|-HT_2RZ(0nR*Q6%FpA`N5!8A9j1_%2RrG=1I2`(3^cf>43sGA8f6YGn)P#lOSdW(u9`Z}^OM_pRMhMvD?5Osaj1oatF92z`Pa&d5Zu6`P$ z`eK}HdTL|nElvP;dk5vt(hxQOMB*FP8z(rbpT~((W8b+eGiHu|c{08+mxqNb?)bbN~PV M07*qoM6N<$f>3)(#Q*>R literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/medal_gold_1.png b/base/resources.pk3dir/gfx/icon16/medal_gold_1.png new file mode 100644 index 0000000000000000000000000000000000000000..87584dc95898d855855de134f117edbbe77c81ea GIT binary patch literal 629 zcmV-*0*d{KP)Z>d?i4qd16vfQzD=mMU~8 zN|%D0Lq)_&gV<4&f zpuMp&KaagxW8&>f()W}Zs$r8288yc4I!3Gr!gBs2b8q(cLfTTC=<7Ux4zR z_uJ;uHfQc0WBfcuN~$?YXrX%_DaIbQb-`^9dy@Vy#CNA=FkUkKsAi?(Xlz3KjY)=y zgCqe7v^VPwDY#O*W*ht7z$DZ;eXnNa6IlEOl4Ig}%259u(~PlmH)~;!`p6YD7PF;^ zOIX~))b-?ha+r3|@RM}>Bq3vVYH1nM9Mt#Z1`-F-1`EW3>L@@IEP@t;=>5}W zkO=d{;*dVjC`}73%))`_ZU8}%qC?1Ojsk*Pm)#ALq_jW2^hOJ$=~42XuXI|hj{wB6 z+}^z3P`3-EG0Y++y(B0}d6MW7K0SZc$TOBl`T$_(adJZfOOuzc*DBSskQf#-q-c?S z+hXhK>qefjIQPt+90~yV{2-YrTGXRsRwC8l!F6c5jCB!~=U#Lhs9%2ozn-rxJP9Nk P00000NkvXXu0mjf!(1iX literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/medal_gold_2.png b/base/resources.pk3dir/gfx/icon16/medal_gold_2.png new file mode 100644 index 0000000000000000000000000000000000000000..fa3a15dd67285af0074b69bb46f3df2860ee7dfc GIT binary patch literal 641 zcmV-{0)G98P)W=215y}4!=PhViQzKob6 zDm^JtBWDj)c(U-6#XIkkeoc;{h#{iZJuE6j)m|RR`#4;(3*aMW5JZL`U8!n!uM>6v zGQ*4DBYDQiX9@&~cnNq31c~IcMT#~~@ZtXsf{%0c_4l(^^Pee&bqeNCHJX~`mmcQr zCnfke_g}!XV;?qJ@nf?%b$gt#Qy3W%Z8I4fjBkJ8VEsY!@_Dy0T$A*>5SNckV=Qpu zVcD{iXskp0i%E)!gCqe7G*_!N@mwljv6UTvU=pevy<4{20WAIjX=CDgO3}_wOj8Oc zZ0^+cLNBD_!gl}eH0Mfl5DMzB-x$zrI#&` z$rNdCey7!7X#^mS`R3}qnz}8>7BGvL^qin1xe206`1D6^WEW2V9G~OIZ?Oe&$to bfco(d?EI=iCbwn$00000NkvXXu0mjfNkJU) literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/medal_gold_3.png b/base/resources.pk3dir/gfx/icon16/medal_gold_3.png new file mode 100644 index 0000000000000000000000000000000000000000..ef1b08b9203d3f24f734288042fe49c9a761330b GIT binary patch literal 634 zcmV-=0)_pFP)MJBXWuWa>}^3xbUnyTHuo)Wv)6?Z%}^KK!Vm-Vjkl z6cxpLr95$jg=edLTDTf?JUMzwMNl=oYa4y5i*Lz$L%j4_`T@JsoU}|m=3U?(K&CH& z7s96Fcwq>aN}t9L4bx~Qi2OH!%>DVcJbP{89Y+hF$p>{*jnIu!b!U0{_ODm z!0%uZViH3TfH)efm8zs%E?u{kz8#pj3gdT6mOG63EszM4xUCRPeq$PvKYgp@wy6y4 zKz&-yj-JE(Hl}e~Nn0_dP1OA*Gja?UQXaU1suV4g!!!a-+KRi97^DH_@F~SXfGC&; zO}o)M)1{jTOYrGFf1qA!=IWTaJ<;PX1Vz#&E}}LFaPg9Ct`G#-{`k`F=E!7*i8g-H ztg|!#keK<#>iw$5n~=?8<}qm}K?!mNd>rug<(q00GQaO5Z9EBP#4%Smf3tL;I01oS zK19+w;jeYppTDg}A+ysjY;j)z!1o8iR9dIvW6I(wx&-1TwK!x+g!$=Ltq1DVKeyPk U$*;Edh5!Hn07*qoM6N<$g5h`|PXGV_ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/medal_gold_add.png b/base/resources.pk3dir/gfx/icon16/medal_gold_add.png new file mode 100644 index 0000000000000000000000000000000000000000..dcade0d8db1e2f08bea2b150c3a6cfe46f694726 GIT binary patch literal 733 zcmV<30wVp1P)D>BNLRMw2ieX^Xozu6uvH&7^%eKL znC@8!5S)MYO_U$9;ldIcHzWA?u7;;exbjDm+^x`csBd!to`_%uTlOK`rL{LNnI@bm zf~g=jLaYMM1FH#N7shSE@%#xH{^t$E>H=#o=OtK%nBQP)h*fn(xOf6_5xGsL^14i6 zUIb^7w#?$4h$$mZ)fLyJ5LdEUM)zrEP>k&f4ggpBa z@$x&AY7v!csq#B4UVqR%axHaW9f$#!{Ix!PyHz|ME%V+qa_Hb*TADZU?8DuqL+@W+ z-G64yGCz%Ai=s=2=sDI?-Tzc%_m*8)-?D4<5v-@#zvBSF=@g*VfSnq~^D^LKa4MBe z`$Tz?thaF^ykuG$HZ^8u`)Cw$#K?$i`ya)=nj)}7#}gp+(28>FZIBmg~+ zPcl037C`v`&7CrABD$s?UK~#*-r;4M@E5h<=hi}IB}dmUXXx!94FueK*GGdFF!1ID zK(9CbodG`I@b)Do3P#ap4b3_RRi&sR25zocS@{_R$AP6l1?U^PJy!Sw9~HhWDlkR3 P00000NkvXXu0mjf{{l-G literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/medal_gold_delete.png b/base/resources.pk3dir/gfx/icon16/medal_gold_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..84b06d5bfdeebc87c663962937c9ea0e8a956bb2 GIT binary patch literal 724 zcmV;_0xSKAP)HY|*JfU$_R_$b0#TLxJ>S10}f2<8B> zL81s68gNmBk0M+Y;j~6&GWcQ%iR1q`h|Lx9uiKM{ev&*o4mATEgXcI|+6M zaRtO_PzszO-`_UuVh*QI$jd+8K%8l#{&HFpD-rt(TnTZyq5?h|MSOwOmeXmIqwTL1 zyp5Z}CA$!tL%gmisz@Wgh&NLNwQDg2n*IiOR~G~c#FxNF73q07&1mm?M*AL8{E=Am zF`M`f+&<7{JIes)K`i)q-umoxry1@0K=HF-_pwVXYTQBTO;`Qf=h>^-{mDX5UcpU@ znMTAcuwK@{vwkxBj*$A)jkTs`7I76Pc*0eSDZY9H9qWl&6;rK>+{hR%lp!_y z8-Lzar<~!+vOOo$$-2#;1hEBNJk7wPUJ9RPs9)_!1cS_sS-y^h&S+_$0|0!vq4vhp zv{_A)v(%XgbdgD2prTM)VvGS_-qj_8gF|p19)P(nFwXL0DoD6AFDg=h=3|k~IRy4M=>;3cvvoB9REhVzD5)-R{V; ztdmly^tR#wN-bwHncQqP1H&-D!yBL=0vbct_24|8&*xB0dBa2m6-W(rcFFayI|V0O zEEbSVCIJ-`HaxIxJ569-41x#Zcj!lY8^JGF%`Wo1U#H_L;37nKHp1{6euL@ zHi90_Pfqi$V$fMU9*6OGOlo@@1UOf%-|vqUMS(;jvEl)BCi7%jhEAt5LW0`HJD}BS zwJuOeRnxSbs;WP)GgLE~OrYIvkMOoCjYi{kD*>%~y{;ii8M_qdX2@JDnqu@YYRzWz bO~ii#xW2)!uhIgp00000NkvXXu0mjf1kCtz literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/medal_silver_2.png b/base/resources.pk3dir/gfx/icon16/medal_silver_2.png new file mode 100644 index 0000000000000000000000000000000000000000..2e0fe75c904b499fbe379a709f324babc75d1aa9 GIT binary patch literal 600 zcmV-e0;m0nP)PbXFR5;6Z zQax)TQ53y1k)0Vo8W9xy1?kpenZ_pNZnOCdDS}O!KnerFBCud(uPZEUtA%Bng%uLr3#se)N9A-Q{mh)+9g~oN*B0mQ00Qh~4);e4nc&Zv^m=46z_kM79tp7M*R_ zo`9|{7z!AW1VcAbgo7Wj2sAg2EU>~fa@hM0P~i6O*r}alzQTvl1dZvy1OqQv!a~g9 z&(m|nc~{`(tGm0gnqy8Y&M(IN~Q9!mjPp}n#<)1^Z6V+&w~JiB#;1}f$O@_eyLO{pqpwe zL?o5T4RuB*uiXh!Y`I)QDwP6sP>yBb`+kDl1Kga+ zK;_+~eL2@OEpkZQLjnW3KP4@@s-Qi~vS2cqklR5_0Pj^F4u_6unvhH;_cEZ)6kZ~c zfNr=_g-)mA;NPk>o6YYB1!y!H4I4$O*riN= mhQh_78DfB_w_2?SmH!XLe!dG_KsR0h0000Ibg? literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/medal_silver_3.png b/base/resources.pk3dir/gfx/icon16/medal_silver_3.png new file mode 100644 index 0000000000000000000000000000000000000000..e385b5467346b43eb436ef98bd9d4ee41d9fdb79 GIT binary patch literal 597 zcmV-b0;>IqP)tuPEh$A>RJ!n2QW;OG4eBo9Fd zsUQ)YODG>7!sWMLFt|LmbWIYBkV1fzA#nCs$TwfXH{e9dg;^3M*mh%LQ)Cox37-%o zA`0-(^BElFY+!2uAzNZvP3EJe%Kd(M`n$s6NbZ~!#Te$6bi+~VgbwLQV|dm zi3HfTt{Zgq^L^aiziI`L- zHPjiEY`YUQndf#Uznt%%8?*KPv+E6{a zmao^AWhsS}yNjSt^OMuMs|ngmr_(T*Oh|1%Mu2nG2ZO;ll}bS-lZkjhoyojpG6~&o zcZ>w}*gK$Tx7+8aq~4dX$*UcXbgFbNF+Y)(tt)yc6D_{WLbu$X|U)87#IOtLseCN zAB)8zG);1!h?Ep(ld#SvQ@z=p!6mC!s|W^zpb6spR>)?vR!>ilSS%KK5n42G&-tG@ zd@p{1tW}_B+e$?(KY96h=@A#PLC@nRw|X~TTF;^+e#1!o0*-bb$4q`Yw6Hw)aCqX# zA-)2QRo?lfo4dQ?GymzwJDfW)2urju7`*~ZFfe@PB1^yN63nyxnbL08R+QvlXcr`0 zJ$Z{axpV0SjvYSBLZ8@t=c&cT#Z8~jhd>~(O9Md=AgdMRH?o*YkMnO+ug9^r^_7=; zCMPE`Ffg#5%jM+N)z$OSXjJOx=zt_iTy?+SkBa<LMIcKp14eyUq)Kd1$B(lLIj2IeBs$f@-Hvy&}y1Tc%uLS002ov JPDHLkV1o5RML+-m literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/medal_silver_delete.png b/base/resources.pk3dir/gfx/icon16/medal_silver_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..06cab467904647ac915ed1d80286709b793d616b GIT binary patch literal 714 zcmV;*0yX`KP)3-Bct`_@l$aK(2lbLuE;;m2Z0V_pBK-p-7ZLPg4qBv$^pvA|$i<6S zgP_nvvC$e3TM-XI4=sYRG{i*7kIioO$M|O5P1BY-@OU$`?|tuk-2$LiUKA+FAQmM43>-u6ko&In@1EQJ{VXr_*un z6NyBW*kq1~NI@yVL{v6~>TY#m9$2^AMIaCWF-RS0p-vdeUGzO)9_85NAF7^R(V&vUz{E7IxP^b z=HN-Yy?gY9?`=HAnVCyaw%5U)EWy9?43qJ3nKOQK#0A)({uhPP&g>5{ks389(J5fz z*8cqOoq}w$Ny(k_>gML=o}wu5`~3$rV2pu>!cafI04Pbn&G4J7RjUgvc9};#m&;uv zCM(HgG8zm9|GiF^MdRgTocOke)8q6{NL94!Ccf8X%h34p06?s4Hk%}n42hZ|3kh+l wr6$?N+@I2}QvbRjTP#kMe^SkKmx=vV@a|w4d?1G z{A&|1yzGF~TZ8KHTl_r*T3@s<=A;pUk6t|eFbv0%74?%+OlCdki0e@06yy3x1%Foo zZA8IP3kLWJ+!ohD8&$%-Xu;s38IP9-L1$fP3CnTSerf$50rgDty6Lr^*!3d)Z5bO| z-!b-f1e)3AZ8+nCGAzU8!LrRAB^VQ3$5hYdKYA07xLVs{S`MaSy~ut|Ll;xQn;C~< zTE=EZ#ZWme+JuKV0b`<5t|FFt=DRug$%=#6R&beFSRGVu!=XktGv>d{p(*$PrItbs zC%{@V&UayoG-zyPh^uwrJq0zft&6HKksgOU)PPF&4Gy0B97SX;1Yuth&KvTM@H8_D zI|j&k17#5C^Q5`mXHM}n5yer~ z1v@0vf}XSMShQ`!KZ;`Qm@#H#oe^ U8%xtYa{vGU07*qoM6N<$f()ing#Z8m literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/money_add.png b/base/resources.pk3dir/gfx/icon16/money_add.png new file mode 100644 index 0000000000000000000000000000000000000000..588fa9d0783d81acbe040f068e8aae43809ba3ed GIT binary patch literal 784 zcmV+r1MmEaP);YQ5ff;UfFtdJ+!s8dg;Nft@+ebwU*P=rQI}aqD!2(VVNRw7ex>S5eQ5K(*jaK z1G#95tuVE@GHJzFl8GEO@ zUBT+8B4M3rhjLVcx?nZ?zX%$}<%!!fZ3w&@gn7z<+CUX5eHH9~A|RF%mT3z1!L{Oq z|IGmOPc#sC%fWLOv;Rs^|45oJPa6<;>&5-oPB<2=s2UPrDBcgvgbLSPToiWavv(v= zj*1heDLwoIte#LpIWB>H!Gg{OGwv>R!WZ{I8W!P-{lfYm1oDx(_4a42#I6^spO^4u zYXiNr-B66xCBbVRNWwx~>df8TR)S%&`H(Ck`f8kPVQN)Jl?>PvH6s3T6{@HV-ZeMG zAt6;pe%D3h*>d(U1cphiNJcER#dHk#-m-((7Bk8eEFYF6!ND4;jM#_As2#qAY)giM zA)uBFv1U9Z4eDL)VrsoJZ-SiIR*lOruX!HVAxt z=$~rQzv6<>e-r1eSr8JEbYUv|b2j|Gd@qcYAo&%QKK@~8xOOYN7C@P&1cVS-=8W&8 z)5AHI%$l^a{Tof8Yfyza3|JN9YS3kFh^Nruf!#Pv>X09#!80qvudQToI zax_Pv4HYrUbf;&M*Zdlyq8?7_RmbIN@>OSd8gKHrfy5_j`{&+3^FIJn1i+n#6MyFb O00001KIqEP)qMo*Mh*; zd8}=$qVq*NBx99ZaL^2)i;wdy8SB4|pz_rwh=wb^H~8+;vno7N8diH65LymE?h(Nf z?1o^7PdOv2^&Hsx^e9?D<*TU>kx2Cu_h`6l!AN2YXlDu*JA_-XlSesY;^R2V9i>Rq zo|4c4R3z0zEe6SgIu}~$Ss%=(AttfqZV~zd-KcPuK_yFsJ9{676QeQ2j)l1J08S{A zVi=MUfq@kC&(-J;Jw|aq2hFb<(KgpiU=!`uRGo~MB}cG2ScAxn1L3YhOy(clY)y|* zFeIab-Bb$dNYqnxbX?=CehVhOJaY~lnQ>SlFqA0(HwKW!}E}Fo%mEf!{6?`Hxd@KqPe-D2Bz6fHeeuNe%wsQ7YxymHtCsikX7kp6pGprGeQG`X(cypEhrPES70s86nE z=+h39P4A`Nz3e!lFE?TR12-O@%Ayg--Gz~qs0~LFllSw8ayxPkWg9O{lV6p*-Fc6* k_mmRH5EYwBM8Q=52dt34J8}-iLjV8(07*qoM6N<$f?4fv82|tP literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/money_dollar.png b/base/resources.pk3dir/gfx/icon16/money_dollar.png new file mode 100644 index 0000000000000000000000000000000000000000..59af163824c44be62dfbb06df9e71769563a33e1 GIT binary patch literal 630 zcmV-+0*U>JP)!DK;9Y=n` ztyZT|d*HtN4z^AtY@ehNsx1Av5@058(+4Yyzw@m$wtszqQ04yGbJhSW-PK+Sn9kpy z6c5&sKH5aCB||O zo)n!;Re(Lq>NlD(Y>~Mm^&rNjF{+zqQYLCFW%O8ObHbFoO{oHG8H;vpFN|zULKkF} znE;czLyw9^s&5nLicTfoh(h`)V!g47a4i6T`6XNhM{_uCpf3fOH)+aUm{Pd%0$HCQ zD`b=e=_a}-!2e?bhS(t8*Bx}jxG|(Bs-8zXGwpDVhfpKF$YwKX2WZW0hO6n{GpNkbaQ6*W`Eo;3}_R5=XK< z0YsI0n43^|QWPahLjCo*dA`zf@Kp|7fal9I=-yn{U+4i*ot*tN)m|#kBeuVS2r=(P z$&2x{rKt;Dqx=3$7Mb}P++9YHsIwW%;gx^mfN*2lS#X?@Zq5b--LhKUKO1nouBZGU QkpKVy07*qoM6N<$f-OlOxc~qF literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/money_euro.png b/base/resources.pk3dir/gfx/icon16/money_euro.png new file mode 100644 index 0000000000000000000000000000000000000000..b322ba9296ace62bce4768154d1d451b9df80066 GIT binary patch literal 605 zcmV-j0;2tiP)sEfkJ^DF^$1U^B4aT>wGyd_KRG3vZ26WF5%bR^MyEuu}!xvI7 zQ4}Uoe0wYvMUju7*jEvjh~~QmnJ%%90SQCmB9*gJSni~-bU}(xuT=+5g+%PHky=$b ztAtNLSnMEvw{i+rv0BowTGVPSi~WZvat{y|&Z~_L5?u;UhnclI<{p)vqxEUT<*BQz zvfi)z!DrXF*rA9oQM7h$yYT+pnbu*xRfYK$;(Lka*052{Pob5$<(3yn4BoU+h_@+x zjWTEN9@;zO2(O!)yifUEJ2BIPhREJWCnrPQoj|d77oF@Qw9+?S2`ddhQ_U#es#KOk rI$x!XulBQYygdf5{#9;h@W1*4h?>zEyRGj_00000NkvXXu0mjfeSH?O literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/money_pound.png b/base/resources.pk3dir/gfx/icon16/money_pound.png new file mode 100644 index 0000000000000000000000000000000000000000..b71136463797cbd9bbee7601fd27ee7f4c6bff02 GIT binary patch literal 565 zcmV-50?Pe~P)~-Etk+scx`tkipse7HYewM-t*f6pyf05Vqlz=?Cx-0Cb?Vi*;@osiZSU+ z^MlKA`@6uHPjYa_ijgecBXjczsZ>Mi@*n=3>DY{yjc@Ll<4u5-uIkC+1B5~qe(Bm+ z;PP}WTC5-BG(>Ycrr0cP2>e(Vov||w@?{NPQqcRC1e-Pfm5JGwcv|N(6|e~fJ(I-# zDloE^U=A;IM9j24k1+6jQtwQ(^~)4tx?RN8H5RtL3JiJUu1H?PK~{sA>T3EHzIy}* zmsSzKc)+h{$!Hqb5*0IDhghg#C#B+dtZYJMtdcTDmQ(ayfK6N@D61f+)`{O^TU5>F zD|q=51{Xg7Sk*m2oNVGRwv#G4M?*~0FL87wP4|u}*gRCwJ{%hOFyI^y+h_dwx=&C* zPO9MKJFG`;;0{tS0gCx8iaCD)9m71|a0S+0Nv4YZV;!NihP@*VyRrsOxz2{eQ&bu=6;*0K>sc1K0N)?)o3UDjKX9=-hzDU3LGfw^jbPZm~2VXaK~yc|hm3 z{CAn)*q^jA?tbg8#{c#mw*7bm5g7w*Eoj-@@V|X;%m4lZz5h$r7rnQvH5VY-01z(O zRPcYwp-KOH_jUizSe|yDU^IgLKQC~9>87Ip#TyF#*Ke==Kk2}P|I-gm{ok^^`G5BE zjQ?57(*Nfz&v}W{fPhK<4So}R8+`k`8^k&t94FzhQIz{|S5h|M&0i`(L}E z>VL}or2k3t6aNEUxDTfRZf$N2uB|Q&Am@h73_Z}ZtNVZUvW(9`QvwfIS6Ve#mRmMh zl$#Uh1-n|?hMZ;D|HEg7-M6f;B+d&I zlf7$HK@h-y`|e%TykI^w7?PY_EJaAPQ54c>8q53x3fJksAZa2BCYUM*sVua!l3=50 z1dSH9NARmNLGvZv<-M8Rv3QsB1}{LI`;8@!q4VZC%_V z($)|W@MebM6lV#a& zfU34!!f@p@U7a0N`V)>GiP;fDG$0YU$1qc=n0xaYRSAaA#PbPt+vx8D8 zB67J83x@zGq~M&(A%HnYBlWn*@^>KYPa(@PqEZCFm(QR6T7^0eIoK=XlUq$sy&MG<48XIWqWo>Z&VtMl{o y&kv0NU}|dWorsL?pTgE;zOB`27yg*S|Hv=)vtlNu1or3v0000+n4X>%=N!&CthHEc zF~($l?$lameM?J=iU3$^sjRGKePaVeATvM&0YoIbMuf7mQig_J0gwf(CzITLG|K;2 z*R4~8VfY7NjM)we)v;p~7v>SGD54-gLRt&jIJ5;TF#i4%;)Eaw0Pp~`))|?AQi@dC zkXTQX3M?XEtPmPUU@~V!*sVZojoZe!2O*<7>0Ph2f+N?>_4mENBq5j zyl8~Z8z-?=h(@CtPipYzMg zwbpN{s;XLzF??7Uo+zoYb@jCkRF}tjJN1(BukV<+eY{BO?*6_zZghIaxeDw_Eu=Em*er{lpj8V(U3^2@blLSQB_P+ zZ7TrxFFs-LOCK;$unQ0bK|?GSqp9gK#u!8d5#hmLlBvZpCKpF&zx0&O*VifV^8wO( zQt0UD_^7q6&+Wi@J&9NIgEJ=@i65=wTVjH-&m(-FP452&``PI`m7TzC;2^LG^o>7W aZ2t|Q2x{GhZjL7a0000&@yin2vZsda%QRL~-#MTLt9f`nYOZPPyx zh@eoS36T*}D;K6x+W3Rik;ZxN{x~g0r!j^4axdp{IrnqUx#wObB1}w7h;t6-9M)Q_ zwHRXxws>l-3$~-9Lj?fVTI%Z?S;=HT1o8t!5I{riG>aY7h|0C)ge>wKDkQi^QO zkY34=4J{&ItPmMTX!1THY|TJxjoZvmDU?#IWerY3D&sMNz{hifYyh0N?ErCkgerop zN0vxC;^igyzK5ssF~scvpr{0;R2~9|Qe;Dm@+7|xxW7w?q6p9T0GOGc`ezsXz~2ri zi3L2legtcUSS-fE{5&TAx5r5r9xSl2ptYv(x&)l{Wy1TnS zYORkJ|GVG`Z6o<;=+J= Z{2PKMYxPLJkEH+r002ovPDHLkV1mLrGgANn literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/monitor_edit.png b/base/resources.pk3dir/gfx/icon16/monitor_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..f772c562f4f5534cd81918f26d60ee96bb039511 GIT binary patch literal 769 zcmV+c1OEJpP)_KmXiXIZwA}WMjL=;76t2RNaR?)&96eLtwL_vXz z78QgPQTDKhZ3bK9gB*tvb)-_Onfbo&-tV@UoIZ)7!@Zn);ojdl|9kEcT5J0H`n2OX zIF5r-3Z)cM%CvV++qTobv9VEj0hCgdl$0_tH3eEjYJk>gKx>^|qc!>Yd31E#2OtfY zn4ILug)aWb&NQ#avaH_#Ddn$_P#P*DC*UVEC!5R+FG*WtO9xwl((t-FjCM4pX#!vX z*tVTY6A(fWPfA87lEh7g)*zL}k`AU!oza?^8Q8XsGo7Ch2qE|umpIxaFWZOL>%nj| z<#e-WWe1*tK{n++rRU<6eQAJpQV8LKBrJtxJ7fp^RA)V7OJS6(*?S3AEN3E8L+`_@ zr_%sj5`+*b2%v>vp7ES*wJ~M|*YV}Ud;G#8cUCbug=Il6r1Tgb1AypIWX6jxDjZ<< zT8q5OZI~nN_ydAyxR>ugB-)xYMxJMYP%uHTY6r>T%NTx% zFQ=Rg8Rd3l9>-g*_fG@Pb#^}4==x;^x$zf~>P=#eJ;K>N&>iP-po?JYfne`~Cth;Lwt9oYdf00000NkvXXu0mjf%FSMP literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/monitor_error.png b/base/resources.pk3dir/gfx/icon16/monitor_error.png new file mode 100644 index 0000000000000000000000000000000000000000..270c5018d2ea1f310c576c0774264dbafd26abf7 GIT binary patch literal 714 zcmV;*0yX`KP)R8*8RG4UJ#ACTJE;QGiL{wIb8 zVz{om3-CNIcO}%-H&7A@Q(s+7VL_0L5|n398nnQ>*#u$)$8i7%04Sxhnt)|lq%$5r zQW?^YMg%-9xSqlBvS&otYoL_E?D$z0mSyoP?P0{Byf{QKXcI7k*LnDThkt>8-d=#QvQ%F#iCM*MenPSqKoa6~~LFXl;$r7J8jC_^SoibqUx30KP3R z?RoLumM=86bWv8*L382}btT={L3=+S913#h%1N{qLZJ|=$t0x(4u#2aN~>b%&1W>7 zy2wEIB?0N#2e>yqJ=L8zWtEpjgqgQyp`omjaU@c}zAIyzddlv-^&)Jk;g z6XgwOFzFe@Y}0wJ9pkQ0SiH!=W9JWlpLuW-hzIfkj^muJt*s^2b6F-qprP*A3b92OyEw$zL wk3ZfA0C+ppxhC2~#0X+cUW#8a1`(P214m|cKIc`U82|tP07*qoM6N<$f@x1W;s5{u literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/monitor_go.png b/base/resources.pk3dir/gfx/icon16/monitor_go.png new file mode 100644 index 0000000000000000000000000000000000000000..8af3eda9f2db79939652cb5f81e045dee47c5395 GIT binary patch literal 696 zcmV;p0!RIcP)a@nqhkOUP*ZVFoTSV`-U zLLou1m(eD{B1k^%wpy{zu%b|qpFOLkE@6vB7_hKA>h3) zK zP*z$(A`uapd<~T~K*0h<7K|}@2%yHW5(nm_ooRO#6M5uc3)WhqL_g+P!#~T49sU+7f9v}oIl}d4E^gJpKD<11TwUzZW)Es3gx6I}K78>1|ykb?Q zx3~AEbM8dZE2|va{&3I9rgH=pf&>I*X5ky@vT8;q`Wc-X)SS0z^Y{9Sqr1Di<9+(k zt<(E2F!}2vPCQ;5E;yp7gz9Z|3{5=c<>#T0EI!!N(^KV~o2{?k$LP--K6rL+--VYz zP~peI6qV&Qy!|@N@TZ|U>uFgBh~xNhCX=DH^%VE-b?{*1239ONZ^`axuL*-KFD&CT=FOSIlydMCoq{ e+1V~F-1Q&8>xzO)Eb}Y?0000 zQ{77xQ565p?E1A+>b7crZ9b%xJqY0!SXit{Ndyr+MD!T!OZ3toQ0zksMIZ)+LJ!eH zYC=Ys2<1aiks0bkf_v7qT}>+0_8&fJgg%&zNNFVW%tIA><=`JLaHd#=PehiQR8 zfHTHmf>LUM5R&z|FbpH>?Z}w9vAVhz(O3*HNz==Ux#f5^HoenXit+KW-2~B%4czE^ zkAJay-d5?LV`IV$r2z*$aG;TkgW&G+zOjUUQr!bd`@gs zgaT1Hx`s&e2(A^C9u}{KbZtebPGN0%0%M^z%qC9m zB$__cvN*EzKVXy|k5}oR3&CO5{~^I0j*3I+9dD5T}ulDl!VvE!ai! zgF;tJnWip?$_)9Adhykcs=98JszFdgM>ITx=ie`2HvR)TU$qEqc3VaPp~La;$9G|^ z{bprFIby-raMpH#B%{z1>)0R%kUH`R9d&uQxW5vbrdb3s(k)2alQ=Xqbf1$=PitXc zlcTs^j;t(^<;}(q$%;#z=F|m)!N{5_xKA&$|^xFLAEzI1^&jSMkZGW}!zxEq#$)AzlP&sV?0000gjy?kL>n$m`}v28ZSU`sZIN*4v83u!ijAR!PX-H4mwUvOQ7QUw2ie;_L< zh_=}XB2-e{*ev2l(xkyunxsiy@;=6UCnhF#p_e!B-WkrEd(O-#LI@lm9}C;I!NamF zIZV?Wdy_{#!MR81ZSzJ2}j z&s)&QQlCKK!%L^rVrAtf>Wv24ZJi$0XA}$H;rIJdE}!CB_&P!hA?)wJ#>`9r)#@3F z#R9U~>{wsHP9}43OV@Sf=;-KbI2;b7QYkc>O#&8?$z&RzK4zWCWYX<&xs-CbjKf10 z^7;G|rGI@K%gf7m*4NixBsVuFp6~9SRVtOK+1Xh{qfzjtYPE_|sbr0hkH6a5+KQ3# znmX*w?RMXupy2xcgVYp1mP8_fwY4?GVlixNY~bSJqD^s+F$8rxh6#K=AE>LWGY4;E z-rnAZ*XxxvTT)fkqiI^2=O-s8`iO}*^z<}$c9J!V&f*6ty88=|+-So6 STiROy0000LLgQ-DDLPW}%f1vx-$*I7)nw zfcOL-13nN51fSzuPw%;K2WgWo(hFy1bAI3VopUb-0Nis+mgRTP0@LZVJ|2(TBuVN& z+EA%fUX@BES3aM=&1SO_aeA}o`uduja5${`{r8$SgJ{Xf~Tbl0moIh539=3k7k0hr@BL z31l*v6h>rm(PgvQz-%_7bK^2GKBhxqVhC2NHLeLH5{diea;bsnvREvrBMKvce}u`E zg2iIl7>&lanm|$%@6in#7|0w)qY)KsG#Vg^A_#&|Ch+0@&2hPl3mJES?)xCRvYE+s z-4Xcgu}8<%1@onPeh#Z-k^REHGlaqtS+3C&f+gG|YbRG-_ zK;8rdgF)bV{)@q2&^;-DALaP?p!n(Ir6dUQ6>oa5+wDEF=^rMO>F8guCh$M?8yO%b UQwmBS=l}o!07*qoM6N<$g0ICJX#fBK literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/mouse_add.png b/base/resources.pk3dir/gfx/icon16/mouse_add.png new file mode 100644 index 0000000000000000000000000000000000000000..65bcab520632ccbd540ded7e01c30af31671dffc GIT binary patch literal 729 zcmV;~0w(>5P) zlih1laTv!H#vr0UAo>ToDcDs6-9&T|1YL9y!5A}ay|RSVC5g70p24(@bj2Xpi0wir zjT4pbI4^u*zOW1N6*L835E%?N=kZ;ie$S7NNp%tX!NZSpc)s87=Xp3s1OTFwmdE3{ zb|RtQ?;mx!TxynO%l~XhBob$0v6wy_4(|nnL6#(48A=_qlVh{l__ejQzs2!*{1g%I z6$%A7K0bzWxeTFD2pkT_w$tfcBB|L_Dg{2D4~$0R#-GWf(P(rxm&*a3e!maGNhXtE zwOV;X049^^fMJ+vwOV~z5Q<5|R3s89WV2c5bUM)M^{4^X;o%|hJP)N(3Cw0Q==J(> zrBXSHT0|C;`kc?_DKZKW8=KqhHXuzporYSiMol@61D#H%5U53DQLhAK0UHT2nG6sz zC>D#*Xf$Y{AvcLeE)(&Q4vk45s8lM~z`*Tx@3&g5 zfe=%g%_dDmV-(OQ zrUbsmmLXi?VA1&)?krw_OHa-kM4^=x5AFcdhlQ9b%sjzd@3GM(U=#1?o(wzpVR7dH z8Z<=d8RaU!umEkZmkO%YDlHrfjn>!K;pWRR_#XQR!{v&*S@_3q}?we7-7i00000 LNkvXXu0mjf((yoF literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/mouse_delete.png b/base/resources.pk3dir/gfx/icon16/mouse_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..72865668cfe796ac531ec2d40a95871aa06da700 GIT binary patch literal 741 zcmV zlTT>UVHn4Mq8SlE-6H5PsAGrDb%@qF1Uv7t%Sd7oEeZe3khvOj&=4ZM>`>dmL0iLN z5dK*n{KGbFfla3{({PH|VmX~Zb^iPIJ}>;ns1C6Q9)9rhe!t((^YH!z0K!Q-5D4_1 zNVvAPru6xIMyJzR{O5&4B5^JrkDH^>=tejkcCw_K$5OAmSS>9riF0#ve~Y)aw$3o| zMlP4b!NCEF#Udh+2;6SBXJuvO6-&)*Z*LS9JjKyNB*=!b6-EJ3BC6h@k zE-s3U09LDYZ)$34#Ar00m4q^O;lbwSW-gP-pw()j)9G*n>izwFh@yx>p#YoB2D8~b zsMG0`q$Ok-Ysb#c4o4;dVbkSivk9U}rBbL?tK8J<^2w;5 z4EcN>^?IE*8PfbFlgV{tu)e+?B18$7Qrhh{YPA}lo0duVL`TLf5C((6cVyuA`*#ly z508YD(r7ezA{mo_zFCJA{=qBwbXx(}-P1ojeezLm5L{l~r8IJvgi>O;T;_&f-%cQ^ zxqxoBIG0HFN@gvCa<5!Oru1lbN9*MeO15tW&QK%xg7!V`F0l zw(0j8jb>1-R?C6|m&U`YtF3~*2fKz-NULP<^()%$KKZl%{sTh;mq%IRcfuwj64Uu_ XBDfTk2IT+r00000NkvXXu0mjfR~lRR literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/mouse_error.png b/base/resources.pk3dir/gfx/icon16/mouse_error.png new file mode 100644 index 0000000000000000000000000000000000000000..bcc156238bc7063b216201aac6c09da7cddcb4cc GIT binary patch literal 790 zcmV+x1L^#UP) zlif>`VHn00M2PU8D2hIa(oQ0R2>*l*in0Si`Z}-(-B`|6$~H+f%Rxz$BlJX9Hqcz! zs=ZsfEi2n6?#tdy)|#7cu08v7SI_gthLlG>aPywr*LD5w3*IUKRXZJy;~IA)oS&bs z)$8?AtyUY^cEROx)j1pv#p2@Pg2iId(xg*cQtPMb(`YnlwOakZ*y(icqT+>6D1=lh zg-9dMB~)-7<0+n-Tc^eo!*3 z1byI5w-EP^H^nu9Qn8g-<~&?zCJy3wqjr%8sb<7EL{-NB9qA^B3=WQ z^&QAXUx4_U!71yJ;l)S<-oUCl>9RaLQ70I9#iHSKZ!hvjqkz9blaq-xxL;qvIxQ~q zqYY`#`M=}6L{Aw2Z+L`H_Z#jA27F6PjqgV59O>>7N@IocpGU!S{m4Zg3+ZX^MS4Pm z@FjukAV0O>x{v%a+&g?oxFgWqTw}j>byzDFbEEBTaqhwCB8mBtThk*Or5!}ax6Dfv zQVy(`NASL5|M<2)6UB>}l*fosew5H8LX*fx*+KH5^8leDqL=I=dhuTJPPE7P2dw8J UZ5DxR`v3p{07*qoM6N<$f`-p)3;+NC literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/music.png b/base/resources.pk3dir/gfx/icon16/music.png new file mode 100644 index 0000000000000000000000000000000000000000..a8b3ede3df956f8d505543b190bc8d1b5b4dce75 GIT binary patch literal 385 zcmV-{0e=38P)klCE>?a@fNhGaV ftv%qM$TQzJ6;XjO8erVL00000NkvXXu0mjfw}q7O literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/new.png b/base/resources.pk3dir/gfx/icon16/new.png new file mode 100644 index 0000000000000000000000000000000000000000..6a9bf0370708a165d3e49047c09e110e02074a53 GIT binary patch literal 378 zcmV-=0fqjFP)Q51$RwCw?WgWe;0fi^vY%UagXRhyB(O=1wVPFJlYqlK$kNFcaSBrLFKHcpU( zVj5rP+%se7wuRup#~J3_|C@8?jsx6(aN8gV+_?~^wID=7QAmWo&=P9GzK~Bj7P?xU z4^LybJ-~;P$nL)ri2Lx-f?f?uyKtX3G(76UWeycgm{0H$eX9nWr+ASHH8>r~vom;o zFz$}vYpDI9TZYLgxm?Z}9nS!RQHI8Y*b~3AE}I>k|Ynq_|_kL0z^} zg`YWG?`i*VRiHt=)+fle*{;CjiLD9r5bPAPFRr!h8&+rODTKm>mjte|vSwTU#7zr+ Y0SIdSJYsEaB>(^b07*qoM6N<$g6XKB5dZ)H literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/newspaper.png b/base/resources.pk3dir/gfx/icon16/newspaper.png new file mode 100644 index 0000000000000000000000000000000000000000..6a2ecce1b85eaa9084b427ee2c5226e2296eaeb8 GIT binary patch literal 658 zcmV;D0&V??P)oVs((xWgD$)EF}_d~6|E9cYZTvaqk~9`i&BW97*P>v z@lDk@Xl;b%^t%HQ(pa0tz@5kM+;h(T<_N&ip(~wEOB0DiJ{F5{;c!^;_xs1dg=jRo z3WY*KAQ0euKA+@K0;yC=8jr^rydICoSglqd_{QV$a4whY=|O=zI1-7hhr=Og4T=Ck z5O8*O_S@lbByBd^lf44TWKv2W^LH=<&(F_6aj;k{L?;9b7K?>5nM{(sFqO3)3}ZrBV@HFj%2boa`NCnylwer*m5<6vU%rtuL2L)a!Nd zJP*qIOD>n6?i;$@!fv-8Tdme9+l?I|%bm;R7`!3)<-bP$-VIIGvB6*%vHYw+%Da)t sWG@c=a1S2nbh=||dPK1BKbT#A0Qk`HN6lbD;Q#;t07*qoM6N<$f^gU==>Px# literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/newspaper_add.png b/base/resources.pk3dir/gfx/icon16/newspaper_add.png new file mode 100644 index 0000000000000000000000000000000000000000..8140e8c1013bc74ac369f84e9dd51f77bb4b84e0 GIT binary patch literal 750 zcmV5IqDdRzdYtFTr{V1TRy&qUdlr6t!*Q zHvj+G^)jT`Lj*H)Do#WSbxu;}#bFcLx8FIWtr%kmew=&HJ)iIS{=WB&02n!{B9VwH z7z|2&zh78dS{nWT`*Gle&*$qdE-oq_k4KoBn;SirKsX#$1p)yE@7C*ebh}*;yytSc z1c$?M@<@RJyu7@;TdUPT&!85dC<^R$`!Ac#7P4BcCk_<|g+eOYEDvA?&d<+-+CjVB z=1vG!EEbDkGMPpXg(MY!sGxH7Vo{$XdszP;zzTENlyx% zk9h>;Pta<$eL)azZ~;0^_Ikbj?d@%l2%JtQ@14OUj@8vwl*?sg3nhFA$PC^i`0_AB zf~AFph5bsUf?}}6s97Lm0lu9MIB38V#JiwE8cW_^Qy?g8R#WzC%N?A##)7aVB z!RF>B3WWl9z>?49am5~0vQ7WIV0H6$&Vq*PnkfE3((CvJv%$wPb3oj*Rj+)oenaY3}jix z?a51sZrE^e1k+|F@b?bP%*>2UPfs^k&+HenzT@#YD6HPq7iWKJrAN?6;~dtkjQ{Ik zP;|4#3z@Uv(P(;VwfY=wRNvK|hhCcCC$pKo4>LGedcA&ZYHDhWV1>bhb=oXY gDa`htSzznG0VN>dZZSF0x&QzG07*qoM6N<$f}9CZOaK4? literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/newspaper_delete.png b/base/resources.pk3dir/gfx/icon16/newspaper_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..bde96ce19ad865893414628a85f933140b50f41a GIT binary patch literal 775 zcmV+i1Ni)jP)4QQaBQ_!nBv1oso6^(<=>w{5>7*5@*yDdEq47ZolibYY&U|OiIrnb>&~VuDcsz2K z%jI`C9Nfgjg!JF{M}Y&AlauA~@o~XsvvFp#S$ZUasi`Ts)9GYzWpi^A<#HJW@0v^| zZe(QS_@M&(u-$I2WHK4hGbjQCLBR0v@Grey?;aW&k{u}EcDv>DF~1Kp&|#!>2w-opVxy*UtizV17UIiDof0s%jFOZ2JtOlz%yG2 zw)auE_&N0U_EtHLYZe9QZ~WNUSaoY_3nT)g(I{qTFo|P!b{5HG65&_^Z=5`XcL}~+ zFOgus)oQJ!QYpmaarpgy5oQjir>BufB(S9G!n@n&!8gm`y(!E1S|puy0cu%TSy{pM z_BPhm))0%uLe;JbAe-wB4g73eq#yllc(#WnbDNIr`KG+Cz%217Lv2#80=S}&DK zSY2HO&-0?~+L9fAUd67{v@fmIk5Q-7H4Y9A=2&KSgejjmyLz%N>!ySO2ACDVQ zptXKi0_q|4*C5ekHTL)SXIXw$U{6oaPIq_rg}JsfFBaM_{>*eVA@@XvMEfzkZI$kM zTO?2a8)cN`a literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/newspaper_go.png b/base/resources.pk3dir/gfx/icon16/newspaper_go.png new file mode 100644 index 0000000000000000000000000000000000000000..fd6142871d234b34bf48ae5b5c86fafaaf36c62c GIT binary patch literal 779 zcmV+m1N8ifP)JNR5;6x zQ(Z_?VHkeSJnLs}CkkC!=4??Q)07hS6YFA8coWfXy6n!PyCB$w(M?0Tk}jkhZxRx3 znh?4{kP zRrRH&X>)Xc==b}Tzuz17K@Jf-ilW>j1c!!(_P?uI}vYw9xZ?LU3SU z;9$9q+iL_yE_ZghT&CICS+F{v&xcSbq|tta;P2|{lK&AH9UW!lVVc>^$TKrDC>Dzl z1OXn82S%e2gM))Ps(HpT;rAjFO5}JvULn_?Ysd4cG)`O1pwY}!<06>hGhs9z6Wq{bqCcdP%@IINv^&2-iB3~f17|P^wXSz(&)6*5Q)9J+g{5+Pjcfj#? zaj~%qpOeeX#Ua9hlE6;q%U-Y76pO`nb!K9e2Si0eLrpVYE!@JwrwNIT5C{auOBv9D zCCkgQjJCEmq*5t_*B@j2^%F>%0_nGc6GzXYxz354n8(}VQ(lC$7(f90jsus&;o!_> zGYW+QY&IK|jD)L>+fa24Bo7Tb(i>}NZMcLjsc87P8r?V_G#o2C$meo73$xE=&SWwr z%Z&Uzy9AkBD4Gmem9e>OxuN6fRFES5MlqAYvo4L`?)Hpbo z{Te>3PGM~E%}+_em2{7u*mV;7`udp2Qd3h?9mjDD}Vk z4@oPLzwY@j^!E0aLUt-_Z)>dhKeO+=m9KzDlQq6w>wzs$CE|-gmFS6MzN~ID=T(;Zo!u3eqqJRXmnn*G;eCR|=#2Caiap};30 zu{1R`B}`6E*4zSIi^;5ubUFsKxY^6C6xh*rLnQG=N$06m?i+3#dpu;atMV&ILn_y z@Aw2qK@9- zWhoksqF5~A`1lw`qY>ld<6!?kkw_pM4s#fZuVS%Snbr39_jyliYwK$nnf3MH-~c;2 zJKXVsfdPnzhZr0jL|a=My1TnUuJby}TUuIvDwWE245HKNiZZ&aCo?lM6`#)styas% z;{Z_<(b(9CKp?>LNF>4yuCK5E-rnB+fB}YwhcCGiR;#tvVzK0COb%gy-rim)6bdvo zHKC)Ug9pnS8X78{ot?W3pwVawH-|)*RZDzIt*)-- z$*TgbcyjBMsp*kkuRo*LuGDJv51QtZqTJQh^^)QRnL002ovPDHLkV1n@`X+{75 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/note.png b/base/resources.pk3dir/gfx/icon16/note.png new file mode 100644 index 0000000000000000000000000000000000000000..244e6ca045c50a130086ac388b560a12761544b4 GIT binary patch literal 500 zcmV z!-sF!^gVb+8rtpyctW0#N6uWni0LCt_6PoOdbjll_d4>B|?abUmpo8>v>h}Zj|Ya;Eu#qwvU1IVc9khP8VrtAsT2=e83P~$#!xXbw)n}FlPSEe7Hq1uCb zR8w;xqmBrUgA^pnkB=O@-lq0DPz$ay0yh_~I_IDpzxRb(4=Iy9CT||k!08w)Pe>W4 zElmH8fF;68$GMwZ#7{4ozI(ySrR%I+xs4-G1q^UxnUV7rlf9>Rn&_6Wike0000v%0y_nie4@QbY&^tbl4Sl(SzV~n0XlZf6UDPQ6j=tD#8}4ezlRG zZ^aZB5eX0zA~r-!fEXXKK7<-;G-5mmHBA?vs9FMRh#tALPC*0|R2D!W_x$pD2Y&uH z+eHxPl@An%I6xt+F{nrb5_%h4!5CaHk12iv=OYr7cNc)uh|`Gk*tX{aE-Y<8V12+K zPJ@IMP&HU1t^{I`U;_tcWvOhrM%lwTT_N$nd1VpvZ#{vt8a*?L@xOx&KnzwFi0yAF zD?5!?55(2Hfm#jH;)`C1wsa8hIuAHpFh_Cx84de(fs`1Y)r`zJmOYQ4l;h7z{??m2 z6NB|tOoR)Q+6LPXG!1ljo}#1m7&G(ZWG2)6`muahZFZcKskR~D8qf$7frn!c bvi<)7-g`sTs&+NB00000NkvXXu0mjf0pJeu literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/note_delete.png b/base/resources.pk3dir/gfx/icon16/note_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..8a1f0ff56f3ff9c1d6e1868eaebab76a185b35d3 GIT binary patch literal 631 zcmV--0*L*IP)X_hQMgJ64VgUTuVX_4iRmQ%|%N&1VIKW z6ly_}Niis=j1O#s|KSprLH24(6;msP^w!;>QD2}~Bd>N!nVR)Lt@FeB=w?vJK@BNvc%LDG&20)2m|BSOT zG|GYVcTq|a#BPX7Q8i>wYmuZj)g4Rb?d zoVa*{?96A>%WfKfzN5XZB^D+3Hxl3sDvoG6cLzPuPx0$};+E57TQ6Xj`pC9+z|{wv zz4sm=4ys+P57Xl7YZ7dNID=S?(*+IABYLga|n=&i1C^Ll$f?5eeicnA#1rn`Vw5g!~Ai_;Six%mol@YXv zpr{DSk_4&HqEGXqMs21Urx~61zW2TFJuNiKk5=8qxp3h5o#%3&zLVh3I}!7>rV zy0cveL@eMS{2@4@V#Ifsc!DulJ&DQpf%Op4v$xe?6=D@)U81WGV*SDrfWQL`Vikx# zC;D5g5L>`a_LDBIB75he%=~zQqY~|505hGQwLEXKi?wPF;-YiIct4j@Rd<3|O#|8C zTHZhC><9zcK%qYMV7$)|Xb?l7a+FlZ5nDj##-OBu%J?oaL+^+>n(`G@l&xA93j+jh z8k0*q$O-j?Nca8_zy`4G;prD4e1YrH!W$vy!p#G|OpS~5?22&Z3S zwVIa$XW=s4>S&U~r@Q#jeV*}=UW(V%W0I-yifB=D-Gvu#7REiau<_yZq|tBhQd7T= z($ZQI{e#oW)d!XmFX`aO{z|uT!vfZZgl-iCb@8i9wMYj?C(+SK{{W>psZ+6os7oDm za8eW+HAssHtztndH5&8%zW06Kd+%{bu?flMg>w%acz!(Rz~hJr|MR*4Wcius>Tg5> zM2Cn85gj1fM~n}l!f1tP4?;!XxoM{rU^Lwa#@py3;K14k2oxWkZ+GCAR)~ur)@w{1 z5V3%RuugCy8}R1M4FaG`bDID#R+pdTbatiw)fl0OJE1u?i$y6E%w! zVqFl81g#Dt0J>IaSeBqk>|w2kSPxY%Q(P@$!YZQc?GCI_sHInE|1+2XL}OHi*zT=Z zU8h#4lGu5M@=C7l1`z<`70{Ix5}64S2PWxB9|IdA#-&~?(=&LIP1_Gq`nEt2iL?V8 z5yJdD#TVBw?h=>~Dwg8YnA%(R zj$TFk{>|*vNOIkQRurG##+`eJ{gcQ0@|wbOj?}J$Sa%+=9>Zg4Z196vY>{n4;~DJ- zSJu{V4^!^$=;eXT={tk_;+R?%k%0G4J~2F&!HM=k{5bFKU(buRM>_(tQzPGpCT4a- zBg=>`HbT&J_h>xL&yOEie0t+?SEq<-KZxb-jd@}Pv9_t?U&mTRWbiM2Xm^@Lr1jze O0000R5;6} zlR-$7K@`V--@00+DaBF-W?)2!79o*g)FH}yo{A10qGLqR*@KDKJa+EdtwTj9l&K)3 z2LlOBDn&C*S6$t2zL_`kI_yf>8U)SZ4Lo?i|9|Ga7pW@$bJ76%<)upQ2dWkohkA#K zMI}Lf0?y#Ypb~>K)OJ3Nb_2Xn-g2{qt_l$p1E7$7cB|Auvc5p2DjMQKHUiZEL@2)q zQEDIR;ys=qLa<9nZVW<#sx92XLNI7BXo#uE+#tC89sr*Jf(8TXibcN{8#LrW1+{xP zkge5%a#8RJW;(ld$se?!rw>(L9V3?ZryF^h$&-Xc4 zn#Bgeig4`EDVplq$eC?A`s&;zw4fx;* zD2p5OoTmDXLoU5Kp}zH~JhS7O#P?t24MDNN_ms*i3Sq zJARohmrsv<9yY}}Fl1l#qhe4OW8)8)+A72gM{638;PD#xwlT-y>N+OoM;MtM{%D2P z=x@u^`J~YsYq7y%#BwszoVwW9!TY&U2B%+7TH(TCpC-}2ZevStYUO;x)y$je!EqaC vU+hy`Y{0((8oQ$vAIdUu@a4;WDm(d~Ny&QoBWxc?00000NkvXXu0mjf`uQqR literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/package.png b/base/resources.pk3dir/gfx/icon16/package.png new file mode 100644 index 0000000000000000000000000000000000000000..da3c2a2d74bab159ba0f65d7db601768258afcb2 GIT binary patch literal 853 zcmV-b1FHOqP)5TQ^(M5v$(QKVE?W+9X! z*o}&~6c?_FreF)9NJB7b5Nbn{G0n4+%uJhR9(V5R|NFTpb|HgjefT!tIhLx@DR+N) zV+fHiR5Yt19}k|KnCsND{tH-`IMJ)3AE?OtyZ4>Un|6(d%h#JK`i&a7^xW9>`yBy` zS4SOHeOpC7$?hH5-#7Rswiue_8Ju*2N@$58=a#2OTA3png`w3v->gWif7t%e$ z$NLVS!tFT#8WL|Wa&K~+{%4P2cRfwesYV1_!F=3OaRVHl(>=`%&{x*s30c}#CNE@&;ItrAv!f!)Oy$Q9t$uS=(sD$-J{T*^(8Eez1E-l3}} zPrfHZ1`qsIFe&gipuL8-IZbo2Yg{lFGKs?ZZWcOaOdk*3`5T;$?AjbG1#`B510Er^h2)2r3Y{!8_2Gj=$KzuN5 zaErtW8W_Y2iJJjY)5pmTVJoPJYpanPOEuYHclM^C1F>${hFRpdi8a<2H|Xudf78bm(zwJ9`K%6I?q*Ua~ fW9JvIbn5*B+_J)rUMBs>00000NkvXXu0mjfH&TkY literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/package_add.png b/base/resources.pk3dir/gfx/icon16/package_add.png new file mode 100644 index 0000000000000000000000000000000000000000..9c8a9da4ae49b7fb02af2eaf6e03e0f6c91ba01a GIT binary patch literal 899 zcmV-}1AP36P)i-HS{zx9u^IUGw>*=$qi z4z(fju8Kxf4E>slBg^es4|nAN~@NV_SFj zT24(nZf1>C;s&Oa#mmJBSw-p_cY~Y6U)hMyiI9#@b2~OpJ~{tQK#e@V>&ZUL%dC-& z4K3ksgdE?;g2XJ7a-IC z{t7T9P!AB)6MkIq=xo`8@fr4Pe+pxHJkq|8i#gBoi7`)S7Dry495@-9|NUzWL5S=I zI}8e@=#j{*V_TIRYJCHM<4>HSsjdT~`23%KH*e}YU%C<>JM(QmG2_K2&b4Ftok-)u zSoT&#!hAJ4MD=!?;n}ksXzJm;^DmMqtaEL0%KcAFfAn>=sgaW^@?6tnFI$DxIX=HQ z$n|KMeH{mAuJ2-I1BCpEP)*e`r0GmDdCv3B-24AN7nLkDp7r6!fpdkQ_POs-o|x$lEQQg9%evW;K1esG{Gik*}W^x_p02 zz@7605mh~*BB$cp`?|L6d!3LNikV3wPMD?CDC_s8?yATc75TAuc)YR+NS+_)L-b>( zsrQ9#j~&5n>ISV5tlihzvj6 zHDtNXPvRAp*~s0*)Qb3}431T$tz$2EYlIs*2)S|cnIwy;Davbif3elb@jZvmT7F@f zVrCSn<#Eb6%J~fW`2`LReM=-(52Z9(N@3-bw6yQ1u^Fa+pFL`;NJ+68qpm}|xr0jX z26asd5=}8;l);+=69sPpD)W@H6BN@|aCaR+jg)K^0RgNik;ZN!P8@G(5-Bbb34>Lh zfsj(mUZRj+Cx|5=>Y#prieRe|9`s;9t61=5{Se?kq8ij zU+()P`Q4A8{?PogZ2858X21%`-aNe960R|t^-p8 z^#MVBA#){3_e)1{XGXDpK1SW_uk7k*rZ%@8*ka79h57N}Tj{Y=&7Ft39^KzhIKCIk zDey{|s*hQ#;kNCD{`WQ~Y=8O)Ay1smDNq0KY^#dAt47{xe`+An-rEnpM}Gb))1Q6G zGp`I%KX;C5B}*A7;LY2^-NEnihO`bR7JkxdbOvtdjHL^v38oUE+~BW@`d1wzX5cwxst&W RBUk_c002ovPDHLkV1h=xq}~7k literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/package_go.png b/base/resources.pk3dir/gfx/icon16/package_go.png new file mode 100644 index 0000000000000000000000000000000000000000..aace63ad6f91537268eb6e9bf328743da7c631c6 GIT binary patch literal 898 zcmV-|1AY97P)yqPWur#3F*- zi1-H*6GJgONgz~1E;+_Oe@~@VF-1Iy-=*@ zV9T!Kgk#%59lVt}Zj7B_)9wTKYBy6YEwPxKqOdeGuEw0%cVhe}Yj*hPSBMNYZ5yz{ z4STT*%d9TVV4NauDND$z(%QKb>=kMr>ckh0lFuesOioc=Nq^^8BQNYYbk1@M%M`O? zh?6H&UZR}Ol3%#RzJX5(MAktmg_e?7`2>w^4^!6w)4$9==U0)EV$}u1A)*bPRF?jv zHdar4EJB1b*f+rh!M+8R159x8%Qjd0I{0j+|69pUC)f(>!P(OTs8c~;XuVtXzfO>s`m zrjW9YI38*Yel_NvP&FVfNEx)sn-kxIx;WzEcpe*LJBYXLr(llS6I0o+c9O z0L_4N7u$0%Dx~ks;fjYRF0OIOR}1uPI!MtibK=J3pihiBTv)jD>R%(Llj(_XFa#mG z6Wg=#j7Q7*PFmM*W@B9!ftm;#qU}sCT;|&KtBZ%Fe#3()Pk+9@Sw&8%k=NQD>92qN zkFT*E2S*%i&!MYvH;;DpF?sU}zb4Mlls)au3~BX$XZr12Z?_sbts>8Fec~0Xl1q`9 zxyH%T#p<5UCqrY2(J4oGEHk9ens22BN3dYXATM07*qoM6N<$g3xBAZ~y=R literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/package_green.png b/base/resources.pk3dir/gfx/icon16/package_green.png new file mode 100644 index 0000000000000000000000000000000000000000..25b28bb6aab661d06764c3f5df40447eafdc0611 GIT binary patch literal 896 zcmV-`1AqL9P)KI|MAoju4i{u@{tJy)-y@2kjrH7x^`PJV~I)v=6C z`lgBuhno6Z8#*uI5{FE53a{TyEIdwPb9zlhuByn*o}qjBCxNBA=lc=8;;-uIZRogw zS=9zw#NJ=#@9`0ibe+Ogc8o$c&USd3bbMh_9cSdZw3#-bprFL3#cPmkBXQjDd5M8x1tTNKZF&VLNYPDZZL9>z@-$o zek7erUNs|}ub$=P&x}PsA(FiZTEG)*B6PT&oEM6I6T4uO&RP6Yi1D2#!M@?3 zj;KdPT+QWuH26CBX>*w061S-HHgF>FB0;keTcKdt%%qe2>11#Wc&Yqlx{|^}k)r#Z zfn$A{-OZ-=^|@K>LVUuw z|4pw?MTXRo;p&#ttpfPljc~ z^*)fFGk3%$D&OKXWdCy9_{b!yT6y_0c7~Gqk-mpj!O8w1MrQtV62N6 zKd51Qa}KVznef~1!f(w((D?|<6MD>btH8XFphvgoMdY%=T+oe>w-3GnExf%dOqtHY zS(}E=dofs^vjBbvF#8tV7ahP{1|};J9#x@ByDLnQ%VJl9Jkj#ok?On}j7gvDZk*=&ZvV1OVY z4lT+p?g&7sR0jS;nIvmd&hhA`>@!j>0=RkO0+JFFArJ^4kx2N8^a=5YR@06hZH)jj zGBW1Ze2nd6Nm9jQr5bhU^{c0-s;WYHc{y@&a-dKs_&%cP^?IL1qnW2^+P(%56&1BE zHa0doIXU@@OnNGiEzexdmY?CSWe7^s)6)~Ova%LQ1*B5x&xj}D{RPNa+l;K6M!5h0 N002ovPDHLkV1m8@u^RvY literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page.png b/base/resources.pk3dir/gfx/icon16/page.png new file mode 100644 index 0000000000000000000000000000000000000000..03ddd799fa0a3aec561c75d4221f195db65d6eb9 GIT binary patch literal 635 zcmV->0)+jEP);68^d)m`eN0o>(5%D`Q(1;j>g@G;xlf`0VBQ`PFY?6)!N&f?*K}$p; zB!U=NBn{eB8${1}&-2_L*HuZp@ZP1@clS@cHp)4iM1ewzw59vko7eMM{e9z|%NNdX z0V;`?KKSzTCvTm5bc{L^CIKLUxc2X{i{ISz$8Sgf{q)1nXTP{`{s?9mQ$4&hPiKC- zY8q7(Y1Xu5iCf33=O4Vy(+|zQ?rW#gkKB0f%}?+6{G*qT22|DQB-73`YzA{N4W^=s zq0kQYcbtFfz zLz)H<&|z(Y4kBG67=JY6c|L1R-#TR>fC$3^Y%QEnYO1xHsf)+GU`3F<{J0kR(;pbF3)zyg$H+idfnl-wl5Wkh!vUH z4Z32YP=l_}1rZd1W_D&^$A($A+&a0e&P?xx0!ctY2}*<#p+qPVN*B(YzvAWXa*%bzq z7Fz41LKILT(GWohi9|LgIzSZBhb*Zf6R6O}WYQ4GOi&71s9lmll0x6;8&ILOl$j(c z0Z1T(6Tg09{?wd{moFHNN6PS?$|e>1MxSJ(0Z7o2)J-Zv|>acY@f`(Y@g7GwsEj5NLQo+q|HsxQ5}XSX_d@*^A9ZT9=A{W~j+$GyI1 zc4oqTHx@1FlRjw4XWyPN5i2~l_F3@aBk!0yu^aoRDvXy}8@HCjUVQUsuSH4$T5|r< zzZOn^?Wfa6y|Q($Hx4{ws+)wX6-HP4zo!S?4KJ@7PG@G3G{CjXs(p*kIrj6rHs7_y z+=<-=Q62s9FuWa^X~WKgJIAAZJR&XBB002ovPDHLkV1jCMPILeO literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_attach.png b/base/resources.pk3dir/gfx/icon16/page_attach.png new file mode 100644 index 0000000000000000000000000000000000000000..89ee2da0753040d1ba0a3487473a715a8fe89322 GIT binary patch literal 794 zcmV+#1LgdQP)i_t#ewV_0K6;=bl;e_Jt7$~$sQ)q$+ia<4Ec+jeaGt9oWH@O|2`W6&O0t!k{B9sUvLWxkCaPsd9W(`fa z;j-|^ZI^2XnzhgZWYRW-kP&J>DWPo`%;JaBX}or79k=+Jo@h%4Eo72tqev+cB?PjP zO<|ByL#>Tehyq$jR74O$B9WDW1`tK`LzYyL3A9iAcRxLkJ`I)n}v%Od-3H>j$OTBtk>(k-9o?8PqI=0 zB&f-+KOXVnjyKJlf4iHOtnuiE_4+ZVJ$dHjU<^o^YCjQ-wt^!;rPpBv(@pFO{9rdw98 z_s@3+yta93oyfL>7AD5}r=|`zS3Gm$_|(iSl8XBd9k%=91J0j2=ivT5cJ18ZmDjh{ z$-RMd{jQ#X79#Sc literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_code.png b/base/resources.pk3dir/gfx/icon16/page_code.png new file mode 100644 index 0000000000000000000000000000000000000000..f7ea90419d950f9e69d977a1f5847456d96a5f0b GIT binary patch literal 818 zcmV-21I_%2P)@LCln44|RX7Ti z0HI3&7jPq){odH{?_{%nYVq_;n_c4WbUpvU(&Cvnj!vq|kVC-vpF6vp^;;e0mm6HW z+WPzA`AZ|;pPp$&dNjzrc??4rt`k%Q1l*u-BPD0MQ}Fbm8jnsyezNt7+u{23>t7Em zJtETY?ja9KrVs^!LJ$xEMF3-bAZO;-IQJavE60KA7fO$VY_%N)R6s>g5mW>fL4&aR z*EVgKKTBXm!=L?S0?xM zYqL@C$|EDF2q*3zWW7;PDZ}SK*IE8;i!3U62=qn80C&*I1Le7WwNP5EcX;_oh2dJn zf#HgBe4@r$GcjHjmj2vAfT%(YN?}kK=(*+1*DkNNc1H5R++vfBMhACi<5uFUU+N4+ z<&U*CPmWi}REa7C6-t>2im1CWv5Jkefxa6>)dEj-CAW wWa{_}BJ!}~75?MkfaCnj>Dn=~vkLS70Pk`;z)@TQj{pDw07*qoM6N<$f@imYHUIzs literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_copy.png b/base/resources.pk3dir/gfx/icon16/page_copy.png new file mode 100644 index 0000000000000000000000000000000000000000..195dc6d6c365d298e466026b37c1959d96119ea7 GIT binary patch literal 663 zcmV;I0%-k-P)^@R5;6Z z(>-WZK@^7J_sq=QY_e{46@P+~LNG}sRzZsxQHvCsN*h5ir6^j7pq-$xu$N#V1gx}9 zClV7;5)7zih-s3DB)G=7|99>ji@So7-P24n=VQ(@GctDX!^_@$bj%oviY6e4Dh;od zooe%Wvs8LEKQ&&bL&@bwi=STIAI@!-gB2jC5+?y?VR~VkrNxam-`6*8&po|RZ5LpS zNKdJ%c4bTX`XjKsnecf%W>1%6WT?pKNdLLq{=(f(Col?P1+oq@R>)W(n=x!|*BIIh z6DJGw_w`)u6yN|vAhMteYK5#b%r5^v+VCFl1IGssaclZZMS{vs-LJ2$)n7DAr6==K z<29#%AXsBsDoO}SBaXR#_Ap!JKx)(1)3O2pj0_dYWz5By*X74fRT01$Fk%P_RzOMDtV?GU{nsYq#K8iy zb6qzLYDj`_f5$BwC*WE(t0m#xYJ*=jC2|HQYHh=pf#QG7oowi`h!L!{DB$8|qY{~X zu8@sU1tWq;n$XThR0%;45mdqXM892|{CJ@0DS*}>?ami06Q_^tvM~Y3K(_-`#m!8f z8f!QIrH4y#61;0Ym0cCoLl8{IPombPHtnn7%SbTdI&G-d>ZQo!_wBMF9nzX!g8HVY xYTJPGciz9XMh3w2fmZ(7v{)r*QZD48?mrio{~IaoqP z|1Ep}yDQG09bP~E^Dk?@JiKQJ z6-pO(3~IOP)IYisL6D6;oAEd;E%zR}{U$rMRNuD6nQV7nesKS>)yLo7JuDCrD>Abi zbj3uW23?^GA}9jQ{M^8v?ejL?HaT7AX5WPZNkBmfN`w-jL?{tT7ykZt$%Yln?p_m~ z-?>&d(LD(jAd}h=LPltPQbO$*Wbyl@G-_k5jXbb#qffHY03>M1jfEqoPJQ6Mr=Byp=^jfzePZV1 zLjCmNi31hdIJHa%e;5g=1(`u3BRzfeExY%=VCu{loOr{`%2hUR*x>tL^W_TTaj);0 zpPR6CUD1+0>4TQ6zVfH3TQ;%l6#(_%yspK@3gcmG#Q4!WCPyLU93nMKk7E2pcA=l45({2jNho>sdF*A~bA zxX?-cp~y_z_kFf+yqu3m#QiB}03?Z&9vvR5TNgj<)($Vm)xq5G>|o2sFMag&6aNF+ WAT1?sQBYt20000iHtsh1EzPArg^Q zIZrOk#rNsfjaSbMAL;<4h;Z=jvu8dzyz8N&Nb7=z03ZUw?9z%8KQEa6yM5=kUnka& z3?FJk2}L7q>na=T#;<7U*P91xfF`;`6%pVgWgRy0?1ZryL@%z52=-!fGXWGEn4M351L4<+7eDgwo|moqXT+s1&Kmn>-uQQ8mL7XY)w5Zk*(g+<3Y3tmkR!bL zOUKaUtj_pX26sH+=Iorwu}MGd`_%O-_sS}8VpG#fJA)Fcs#ezwtZf?q?Ac70mDv`rVs{$od?VPKeqf<-kUjNtS6ecB*mq<&M97K^6IVsDO zt2$Ru!b+>2S<}_H>$RcInusU_8PMNdf(W{sNlJ3FkrwMJPeBPO#d}Y^a{9TH(#{Y) l0D?dWAV4eUJX#h`!2gmISk&ZKd4B)^002ovPDHLkV1g&sd|Lnj literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_error.png b/base/resources.pk3dir/gfx/icon16/page_error.png new file mode 100644 index 0000000000000000000000000000000000000000..f07f449a44ff2761bfc7b752db3d08d0e1238b02 GIT binary patch literal 793 zcmV+!1LpjRP)lHwhvrAu0-@MQwt}+5~MQTtu}C0%;W( z1<{R?aHBz*g;pk%AyQVBR_Zu5m~;ES_vxI-O!vIF|H*|T{l`n#garr?$RMk>)?Y48 z(ZF2yTneKb};DNWF+jK)IF`6_IfJ{i|F3o%Q+l&4_HGBD|ACE8na_6>L z=s{^>-C(a7J$6=8A_%h5W!1K6dcL!D?XX+Ndk)oei?UundDpX_E&1Y&`)3P8#Ny0s z2Ag7_&ZPhyGj%)g&S6V2LNun1;iBQm#Fwlfv zgyESZR$X}2P;=RW!2zid1r$hBL{K7>2qi*f7>pT1=RdT3@-anEoH{ z={KFOO;Dh#bV*jaN>}M>RZqQd`S=6O9C3KpI~I>l%QFYfo;jqQYe5fcn`)+)zMm6P z4X&L(>gnN0!%J4^rhX->?$S5bY<=GEU%jc!KLL8sww-Eg;h z`H-yBHa)yfojYT}&G*GFc$<(Yja_q=lZvj66DC^O5%$B)|Z(CeD=n`|eM04SP; z>-=-l+xdJjA~vR6^xB#o{ehf~tSM`iwaQv$O<8NIHA}W_WOw*~ XD^gE}t;YAo00000NkvXXu0mjfl6ZQ> literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_excel.png b/base/resources.pk3dir/gfx/icon16/page_excel.png new file mode 100644 index 0000000000000000000000000000000000000000..eb6158eb5ca9c4b64c81e70e0fd894dbc8e2bed9 GIT binary patch literal 817 zcmV-11J3-3P)hdKqhFO_H1|Vn1E?(=|cjAh_&P}y{{^`u< zcYD@PK?$)4i~7o9*6F_$F$4lR(d4AAvrez^(88Hk+)+B7E)M3jc=Ewl4$S^`_qwSF zA%qz@=c2EOsz@0qB1IqsqJU)HaG&+}%`-OM8YqW{K85hqj@4&V9vz!Cm_n0-W#f;# zeEpJde%vdgRn5?(+PY=W*z~|lT2-mtown({ll8&3S5+lWz5K}LTRW{k{eJn3Qz!SU zQ`@qI_n2;K?RG~pYJ9=dj-RWgG;P&wEuoAxL~Q)<>x0b=dED^Outj&xQ^rA;u3pw| zca_ClTh_d9cxXg_U!lLRl0`xU@$=UXO|_dRdtXfKwPawmnf(LC7u}-U>8k6}3u|{8 zs9LHr>MIJZGD^r9h|q2yF24Wuh+PM^yMN9GP1$khlDkdyCY}D{kg}jEf-(kW5jBY> z0rB29ZhG-r=i_R{;+1k0?A-sBM;AP6(k1i9ZuixR4?MqXOvphQgCYj~RnXKKL~J9Q zIDNz~XMfO{ZhUg&BTtMyXJqDVqc<x643?SvKHx004lTvR=0a5$dUw z>Xb470000$S;ka1sfH4I-R8njUol7M4dtApOahDylptpYswf1hD#CwFoz6oEA>(SIECU&IQ%a}GXdnC!9$70`0uH1B00000NkvXXu0mjf!8w72 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_find.png b/base/resources.pk3dir/gfx/icon16/page_find.png new file mode 100644 index 0000000000000000000000000000000000000000..2f193889f7ea091c292acdd684c595dcb206b5c4 GIT binary patch literal 879 zcmV-#1CacQP)@+1&aazfGU7ezSm^v zpACwO+tu0su66!(dT=`e05DeeCnCFJW(8|RKtKa{4LGONnx2V85A4m%PEQ?MEtR-esdM$pB-`H542D0)N2zSC6Imf)4L8?>%ZrW+H>xCKi$unm zvGZq-*Q%Aahx;C*=l+K%-?>XB)6TB$-L$r*`RUvlA`xP1NG2?)ge8@TQ4EN|Jks0u zcDg;oFC#-#R`YbWB`D?Q`1#y7l$LXhjSLf8AvQuB84}i#j0^!#g{VE#(K7h@5pFHy zSenl=@XBEdxp`h2Ji>CR%=qXJ7!e|?paKet-~;#ok#jETyeB(5&Bkhp;!+;51~G=) zH?L7xmDUu_h+a$+xuWom;AWW!mS$%%+436Rjc@}y?l1134kgD0AOf$OmjOR zstUlshZk$ZC!bAyIg{Y29z#&@3SJ;6D4+_eFume9^#TmMccC5u0J!ZCTnO6m$lnD| z5JeFHf`Xs~1vP>RLKI1GKDY<~pjr2&bi(fX;6Nj-ss@Ds0CcoO0H{JsEQkm{q03skAA);_bv3q{k31qwVo&s-q`Z?_e+j^w(WL? zl+uETs5+~xBU2};OqEE9ETLGwsMGe1%iTRNue)9}|0~E4B*@5#oRXZ9oRXZ9TqRep zPrGZuoOON4n@=uPbyP1y4G=+HktC6l(gZoFD>@_lXDrN?wo+zozGt3P=Qh+3L7+}q z2!WK7geXLnO3Vw;o12Skp%_E#+N#9;DDWP?Q-VS3B$v~Ha)dDzWn0zG~O(^_1!n0HYp-( z+;wPIdoFgQlpYV!10V>5@a)1LyGBMvoa}miyp(bxbMTM-FYNyx;V@TfYddyT00000 LNkvXXu0mjf90!wr literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_go.png b/base/resources.pk3dir/gfx/icon16/page_go.png new file mode 100644 index 0000000000000000000000000000000000000000..80fe1ed0cc75fbb67e9398ae686641f8fb287238 GIT binary patch literal 779 zcmV+m1N8ifP)JNR2Ufr z!Apo%Wf%b9=l#x^8AolrB&K9H?Pg_|78WA8(M3toqE%3B#7*srcF`i*xhupr27%Nr ziguah1+mN)U5GNmyEfQ3-e%_i&-vb-Co#(>FJ+EhQEwjRYVQ(&UYy{U@%vbY||>@4x=B^vIqabI?L* z;-S&DS^V3-ni4^fl|HMkOEbgX)(390>A}|VIypb5Xee4g;7ck zwKh^A3Mi1Mh@eC$5lV!}Fw%sP623U`g3pd_Hr5sunLvTskx4}&Gm%Q6L}(l4x}jCe z*81q1_4-O*ffi~_nMslo?EQ8t*&Ec(pzEw$vc}pKn_Qp0>D7Jr>ATNC3w@9f|Y+U&+)#!t7l&wKp+nP{PQsb+fb=Yf!Fu&5j8vpRj{FT>jD z>d>$sx;A&+`n$HcF}&sYKSyR;=(=9tvvOj@hUG;~4qTYk^_@E=?$*^_pVh_bGnOt~ z;pEw)j{SK$XVc;qy181rT655gW9NG{(yeablViIL>cDI_ux8m>Pp{tY$J0lgo4#ax za?j0EA3s0S!f>{~ykN9h_RhM&g3K(E`q(dE(Rd49+%xMeR9{qlWnmd{s#(SQ>PmFtSQqUjAtB;_Vvt6}AS_5YgM`Uqu`yva+H8^=4U$e4gHb}u zAQ2N{V3A%pO|?Pv?tb6z=jC}SiRa$G^v3q?*6XcYz$p|cq{uLj@#~Fi`J(>5{@&&N zy%T^+;>8cXx%|o77anP?&W1?1A(>-T49z9pyeCl@7YI+Si zKti7=B~``}TImz(G{0PnlQA3P#MAd}sorMjkP!50B7$nAkU^%#nl{Q9lW0@}9fE-> zN(q7tRuiC_T1r|BBtVBTlQ2+70$Rf;eF`Z;lx46Cpu-rEgb)EBKq(b^W8l<^We(`D z43?0=01z<3G6+UUv6`CsWCk6^93!#+<;ws7007{zS3k2k9-zZKFO~(k`>s0y006+1 zgF_jyIhsL-`FMf~JL~C=cV75(CrJ|q;MVO961G=O zm9d)YpJg5g(4i_HKL75eSE}mq$Y}r}hyVdcV~p>6a}oXr80q`oj%+s700000NkvXX Hu0mjfPs|!l literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_key.png b/base/resources.pk3dir/gfx/icon16/page_key.png new file mode 100644 index 0000000000000000000000000000000000000000..d6626cb09eb11a298b90a8a27b0d8eab41f49a82 GIT binary patch literal 801 zcmV++1K#|JP)$lC4gU2-`f*>nhR-;k6IP7e>YO!0^w)WK%3$w02v-#>5Ep64PCP| zJihT#O|N+nT7XR2h7dAB?UEAOhJF^mol1i`QtQB`HSY}RE7=r! z)zaVIHr5?>v2Gz&fdYw&2ug$!p+txby(aWZ7(4QT)l2`jX7eMQ{>)lG6ev(fWKxmH zOr%mM5$6B%u~qGtCf40#`mbGj3s!n+^%wnJ&#rl>g<4Z)lB5J6f!?|AP275)Zswr* z%T}4~{;_(?waU!#?JabbF3Cy-kf0{R{z}6$e=5yMQKt3BPcl2>zoTPMqMwF;3!_n|>sT?~bK_-2O_m+o>GJ6h zt=+g$4n7y%1qVJI7*5Yw(hqM=JusY{d}*?U(Oj*gT655eZ>Ksn(qrd7v3}DX1}C>` z+X+8@+4-pVq_fxG zlU}~Ye!0+%>J+pPk+0wV{GM$QaYM?5ux)w2z59=S&H2+K?;gH$bZGzL&g5>G ft+noNiyiPkP9r@8gT|RZ00000NkvXXu0mjfuqTIu literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_lightning.png b/base/resources.pk3dir/gfx/icon16/page_lightning.png new file mode 100644 index 0000000000000000000000000000000000000000..7e568703d6432c530224e443771a04fc1e2e59c6 GIT binary patch literal 839 zcmV-N1GxN&P)73{`^;G#xwAtHz%LU)4b zqTRU=ve1RNa3QT=ZM7C`iJ~QFQ*9t7<~pX$d^7W%^M8FFCkcQj-~0ZRTBCB(J0^iD z-~e!d9LR`f3#|=(>$bPvx_D-~2jC%pJ=n_e_OK zeJ_2b-KdDDh@@UlzBSMC;EPygH_MwjWBnPGQegihBV73D?-x9PlHL9A=(Vg=8^d<4 z<9r=UkxuIm)*CO=9e###7PztDxUv}e?$0)rQicmYhV`pQ%S!g@;K(?TVfhM#E?bM| z=B0gfb6h@a8bf5FVT-SV~6}?X}9lK@@Yynoty&1zdZP@?RfODsl=2XzzU% zS8gIN43How+9%bK2S@Xbc`O>`z5`%^;pXGy8^4f>9^3!Sp@|O&)m;dOa3q6d;4P-l zca|=H_{G&m?D_+&-}r{u-J$5T=(X4R&)q|O^gN8cgv;s#@5sEPT5_Z)oFo9Ac>l+I zc4ng5zHpps|9)<_Rw>5bKzE(M1j)dFWI_%OH$BJSz0?T+02W0)_a>#vFqb!*d|5wB zzBUN|M&ty51O@=i?kiDrjQ{{}e|^rU?OS|RdxxP1p5mAw36cX72#`R6UsoeCQFI~! z0ATITp!vfeYyQ?Dr=^5BAshfEa0nB~JG?nUa2Aur006MC*<9`)86SPS(W^`H2n+xi ztOWohsFfVfVWrI7PSKW}BmkyPoj(-|J?ES|BGd-}fIxr{00@ANnO*ZR`#)pee4I5T Rmm>fG002ovPDHLkV1i|Hc$okI literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_link.png b/base/resources.pk3dir/gfx/icon16/page_link.png new file mode 100644 index 0000000000000000000000000000000000000000..312eab0914ab59271384686255d1be913a6b3add GIT binary patch literal 830 zcmV-E1Ht@>P)VWgGzD=Y79#JI$lhEn`|2MpRa?Bt#-nSD~P0P(mbVe{KrOBoKnSsk>m|ML{6l zBosu@om4j#WzNLRAk+{k1JRvL(MfE&vvbb->v>W{*z*1_uMP}0cIRX*?mz+wk%*#O z%0D-+$B*g1nRkvI+_3E8Pr1NC6@5M&4vWaLCnNlr;lNlr4i91z&)eBGqL{L{GNu;Fof}GS9{gM5BJuH;2QWk8yuOZdB3pGR#s8bd~ zAmt<>3Q=YH$t5YJ5;7@+8Uh6=ktBgY6#6Pa%2F?h910?U8cLT43KAj$Z1*==ra&gILO{WkHfs(--F=bly9l~${z@AT>V$oat!YAD@M zBE0v_F{`g#^wOSP-u~!wvlmXdd*uqFqoZ0^{&nEMDU+=!>({S0wrQhFmoB}Yq1)~0 z^{A)L8Xjzdr(W4_exYO6u3a{4*kIeXZMJUR>Q=ksjW_p!rAwDKYUs90>6Q|C>56o@ zbrSq^Xk7Gq#>dAsn@un`Hz$?w$;Ss`%jV7L%9ShgHFV~C)6M>B`Tp%|nqPc&G*A3| z)Qe+}vT4-x^t1~XE@(6wR;^lPWMo9n*~E!cy~)YRsT2{`?fqeIw-e7N@mOA%UcCIq z_kH(_EK7|>pM*1Wt2^DaDAp|cvp*@(ZZDKpYkKC^?97(`0sb&XTXy7N#sB~S07*qo IM6N<$f;YmCWB>pF literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_paintbrush.png b/base/resources.pk3dir/gfx/icon16/page_paintbrush.png new file mode 100644 index 0000000000000000000000000000000000000000..246a2f0b426faa0c7f5ba009e32b1deaf88d1288 GIT binary patch literal 813 zcmV+|1JeA7P)otxGRZMDZ!_a~nK|b_-`n%VosaL{KDuPV10`(1LIen8kX2Xff$3BE zah#djvFGJ&eE^89Pk*-O^+&d>FC~^GjRYVQ(uuPJyS|-v?9lxA-+tM5>1Qu*n+Ir1 z6KhA>X4$XDH6?-|E5oe1E?pQ5-M;2xw_ex!x}I2+b=}mPFW$U%^;o(Zg*LP!K^1kP%8ynsD^= z1y^6xD1#GLjO{VLdh@0GKY7;d$+NGukV)GRLPn^=q=dF%B#XaJrNP`0E6=}e&Gj3d zKJbQre*WXt!60_DnIzgMQc6S#fvjXxsE1v7;T;njHkdy2miIqAS(nX~o%cO+q+b#h z5tIleLWvL=dQE8OC#{%y*Tnku&K`Tuub&_ELI0t_ea{@3f>Jv&sYqld(%}3_GY3Dm z;O{3*Y?v^A`a|D;^qrM=ykI)U6QHd%WhO~VF!SGjGn0GOZrc3mGZudNl9{Q#X5&-F zuGwVReFLBjE5jr!!^-5*L%!I%PkYH#Hs5rMrEBl^)9)9XTD;xjHFxVZMc3~Dw6#k$ z(-S}RE$bgMHv6Z`mS5|u$$78sp4G-8b@lVkl`HtEv+MGn!F&bKcHPi$$oP_;=BrPf z$(~b3&p3CsuQxhoV$%jIR;`lB-s7FDX)xCTXuJ7ZyIQk96uIR=HBt%-P?N*bp`)EF zq14c}QM+O70NTOa@V~_)&GMZ$^cQDlkyOCa(H3Mf+6xhCuZh`VSN{cQBl5Ys9{cp( rh`2H3A^=GuC6HjQ*7|*0>;m{7QlnX3z3MSD00000NkvXXu0mjfR5FYo literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_paste.png b/base/resources.pk3dir/gfx/icon16/page_paste.png new file mode 100644 index 0000000000000000000000000000000000000000..968f073fdddc1cc0f0800b1ac4001cd9a55f053d GIT binary patch literal 703 zcmV;w0zmzVP)AVs!l4K}n~L(tL`6d4Up4iSWnZ3Qg~4n+_J zDGk-qQdogO5JUtO-d5pRp7Nd7_r1^a|M&Zq%mn9Oe((|e0sw%Ur!K7T1pojj=U#f? zQM`qbQrM^DPkwa?DK_be^~z<~RgSMIa<`xP_4P7gg2jCwJ{9^k!fsU=#Ti|%I3p;>90Qd+7|~0h&mIklA#nb>ATL2+v$&u)OBgB z;nsHb)I&QRKeX40H~~cIZxCd}5C} z=79lXoXK%6YlyLtsV$~bSm?Upq|DJh#{|*a7XMm`4QJWZ>s6nL2R1|&J z0VPEwJ9?!n`o5PKAjc->P1Gi8BY*%!5&FVp=#)$mMJYul1Jton}gujiUf??eOy!x&!tsjxy;=Q3_DdcXx=a^OBhW0N~`A@4xB0a*%F? l+@c^sQA%W+?pa#c`9H5UNfS6T{e=Jk002ovPDHLkV1grvM=byV literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_red.png b/base/resources.pk3dir/gfx/icon16/page_red.png new file mode 100644 index 0000000000000000000000000000000000000000..0b18247da5850f3c2486373a3e179acd2772e8aa GIT binary patch literal 641 zcmV-{0)G98P);68^@7JE5sw#jpE*579S@TLkU(6yap1yN*Zuy>-hV%Q_v4Ar&!63c8OBr(ZRhFu z_kWs36-AmgZCT>x!RqM;Zu9tqvoHI~k@UmYo_g(*J3c%2{N8}7I+|qKPQzv}7t>%W zsu&9G)UmCzkDYSw{fBnuW4j;1fKV_nicw`$8C6D=F_qu`zUiK$2Oc?5UVY+D(`I@R zW`KlwqLftWHH3Z2_XVNfKn>VgT~k=@- z+N>c>0|@A_HbI9Jn`v0~7cfIF(TS69zaomDS1QtgvaBBfGEPLHccO2~3jc>n^6}^HAEh-2#VxC7YYcDXv!L9X= z-R*SOUvIs;n`8(LxP4~^2|JsiN^hq6cU}5dn4v1~Kl{eT7pm&f$PoY`hyVe%y8G*S bxB&kH@RuR86sIAS00000NkvXXu0mjfZBi!% literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_refresh.png b/base/resources.pk3dir/gfx/icon16/page_refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..cf347c7d4685128a4a447abb9fb8e939417644f4 GIT binary patch literal 858 zcmV-g1Eu_lP)`6pHR2Ufr z!EI=jWf;Km|8+n2IrHqe<9xxFVk)&(Nh?w$Xk`TAyvb=#e=0aySC z00NkRDM597_LiNIJ2M^qhuTvB004REvvU8@of{r?P8tmo3;+Pk0F0@*jAMhdOkS&1 zhJPPfQa;pP0|4+Yk%#j>X}o-s#EF1_DMV93FsfPP`G*>Ks>L&)Q}w2g%slu0kBfW1 z+*$*0BC^oTl6>OGIq(9BgG4|C90Dk-N_mPazGrQ7uHZ|>BLD!-KmZ)z1e^#?1Sf(M z!6m}K(^b|i%$TcA5bC}r$tAA?0C)g1@CgWliJ;NAk&ZF+-w#}$`-3nZ32C6IVKrHp zr+(!L2hRfF&AsTw>_@ z1y23;E%Oz}?q^Q2d($ayO;-sON2t7$w(Z|o0Pw1YnSp^}0PI+I5HnDNsFCA?oorkG z5sUIGIq=FSyxcj+xlhkm0en=52Bx3@02o12gdAU$_i?v6iyFMuc7P9#zQ-Hf; zVuV$t9P5`m)F2w1?t6{<8%wk{w-PP#Sj#%1MbsjrSI6n;D_@8q9`~W98dNQf$j=iI z6~hpgww&be%X_HI50Hhx@W==u4TLPB;ei-J-1}G8wH}|{i#Lk-WZAyfv}k4y0|fvU zZTy^$u6L>2nWo(NDSV2@MRD}JQ4(c%G%=dG@_vxH?>gcH#*Ue2HC}9sapf8X?R$Z;XEnm&g zW99mh)5jNw008mK8)r^`_{yH0rNn%u1|SpC(tjf#om=+r#lh+?Kb>DVb9`|C0Bvbv zN3U(>f4-tAC1hosRoA7p(b(hL*V}(j>ug<`&U)|l$6o$)!>PBQ9RQSwn9asj2p*|xhU*R^vq?*Twb0t!lm5}`yW5lRy-U0ZYK?8to!;o!r!XeOE$ z0HB3T+6EEoI4PlR=wonwqJ+TvCoWh&$?CAPVYcU= zD{DS0?AkOtb@-hh^ZLq~FMjxYf19X?pa_YqtgZGvv2TaxcF#KT?O%=_*a-kW_;N|D zakkWsOe!)HsT5WRBiC+p;N-c>0Qwy(1D2MDBC595oXSiR07)sKNk-%9*rDBOO^HUD zZW#;)R&EZpqha<(HK$(tZYU#V29<@0qCXgU{gXeGpc_|pTqQD-WO|}%yKZbeX7k*H z2W~CK$v8NBAq~czrc5A(v51g0Wma7`G8}f=ZcuAiYYxZan@gP(;Ku66M6?bquGiHe z3Q0ya)%Lvk@kLixZfZyU@#UFbv+>pYhcj8TRKSr_sWG8i^X~UA**LvbD3(_Lba3xm ziYcpup*A9qJ$?AA=Og05lndxfwr`!C+O~h|B~4 z01q8H`StcY);%&mId7_+)76ovRpeNWRp&4M?#jx@|E-)x%P*A6t^fc407*qoM6N<$ Ef@ddc(f|Me literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white.png b/base/resources.pk3dir/gfx/icon16/page_white.png new file mode 100644 index 0000000000000000000000000000000000000000..8b8b1ca0000bc8fa8d0379926736029f8fabe364 GIT binary patch literal 294 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-&H;pyTSqH(@-Vl>|&1p(LP>kg~E zYiz5X^`c$+%8#zC{u)yfe-5 zmgid={Z3k(ERKCKrE7DF;=x4^O+ pzO8rLO8p|Ip=x)jHOtWj`bJBmKdh_V<`47(gQu&X%Q~loCIFbEay|e6 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_acrobat.png b/base/resources.pk3dir/gfx/icon16/page_white_acrobat.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8095e46fa4965700afe1f9d065d8a37b101676 GIT binary patch literal 591 zcmV-V0~O9lw>B8WRlD)Gm}Jrz31u-X&&gn2lvjs=i{7nIaL6v2==uw+8Lcs(8j27 z;|c`rmSv@Lx!heopGP^^Ieb3f=R!%Lpp$}iMS-&P3EJ)s48wrJ_Ni0~k|c47D2nj= z{jS6bt|kFpFf|p5cM`_&0Zh|`rfEp0(}=}lT#(6RpzAsUfxv^LSYX>WlAaN$>)*J5 z0#sE+JRUD8iT9*fz{)_^7@6P&!sEjTcD+I9Z4YjT1`wH@fV{cEvneYGFU%maIEU2s55&K(LixD|{p-uiS@?KNj zk-Go8G$hH6g002ovPDHLkV1hVj1#|!a literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_actionscript.png b/base/resources.pk3dir/gfx/icon16/page_white_actionscript.png new file mode 100644 index 0000000000000000000000000000000000000000..159b24075191fc259cfd80c797a1b0d74c168422 GIT binary patch literal 664 zcmV;J0%!e+P)7Z7t2}reCh0o`+ zAlt$F2tW%oO@m<=(B8a-_VgLl#~yUMUDWG!0qFPppd^03e+x1WpkO1NhIaKD2A)-@ z=Py8(Wi%R%JtYZG#sTKH@6Z+&!S3Edf8jFJJNKuva#KJQD3X^7;H^fd2di znEN&c58aUG>`>P{Vqq$kLb+TP{?I!d4(|o59X_%|nVEZq2Rk60n7072SWJ{64CV?3 zgS!EB=eYxwQ>P2&$}(iT6UMvuFgHHIEdNA29!EBtg=v~X!DxxEH~}L2zn|52%xalaq@DTdhh{EVwv0IaQ=!?daer zTKp4I`l8SDt;d{8Q`5Ko;BXUi&oAG1l4}59P-{|^S(Rmord5s6qsh<&m@Ab^wqCD) zHyRD}lKLDzpYN&@q5&*47mGzGiqcXpmqR9#K|CH8kXS4RNs`(iEF%HjP%f8ItyaZK z6$%Apvsok(2>~dTO5jTZfq;N?0ch4l01f$k9?4{~Youl-#x{UDMr#AFIkz@SDwPtQ z$gQ^$2|*(Ps9LQiav_8o8Ne<=Zx1*M*syo80sEO1tB%>5 zfdHB`1z+!R@?ghPRKmL)hWEvZE$=*54ose*0JiUNTM_)cMDXhxEKg(?-pD=y<)L4J zT0dSyD0&NhJ$^_8Ko9uom%-ZM4BTM{Tw$9qyPj=-9W;N(Wi@3*-Q4pq`Gcp}^vvNr zyd&PsmG>fpCSZz?K}UIEd;HGgG%0MG>ymxKPwy{>wy(m*Atq7)0000~7 zMNw2LQirBVQoa8G3P(rY+l;L4iy+JwSqmy$9JlSkk z&*$^Eg+c)@!R|v4gdc8+TTn&eWHO0VD&>$!B%o;;WLf4CNs=Inq9d`xA4otCWHK38 zmc{pkX`0Y=9g3oGK{}lVy~OYL|C5lQ&U^l;wrg|7w=BcA9L4-r411?K7f`@348&rw zXD#uW)DK;H`hxO}u%=@Cj{;#u#_;bb1_KgUOT2Hp6;)MvC6P$vQP3=g1O5#aU%I!K zZ1dc@f}YvG&*Spnplm2rIp^VdA^HydZ0X1axdms2!RKi5x-SFA4p@ zC@N|PI$ryHL@t-(!zBsf2-+sYAukhDHU7Lxm88-p zDk^c;sHj}OKUc4lGZU}6umlGVNAJx0%sKDOFwQx|V2pVvxhYKe|L9TNk!~md3BVrm zYPDL8Hk*yU-ER3~LGwJ7N`0ZV&nOhBI{~~A;@ND*=kxg?#^W&`4u`zk?Mg_e)8XlK z`T#M+OaR1!<#Nf_>$S`xrqd}OjYhoJ>q)?3vEX8pY&I()ERjfjrXM$k7e+-Qs3Ihj zNyOuEQ2EGYG7ro!o6VOBQEwuV2z)*tR8>WxP{616FY)p1Pn1d}#9}cxolZC$4n(6- z35hJq0;FlHC{ zp*iF(lgUK(E`($(s9pJ8Kn?(M734H_63WHtf}6SQQ_MXEP!#0|&@>J8dL5TfG&tBw z#tYn{TCGZvAr>cca%YYn^!t73tg8OOJ2FvJ(`YpCyVZi*?Ur+1uUA$hAg8-aK)c;e zQ<)!XwHh|n&ND=$@^)>aF-`~n}#*WMkD*M|f8r$i*z7+W! qF|A!t*4fE(R`<_YIkN&?Jng?3oQ|aAqClPi0000t>5xmo{nArfL4CJwMMm+N`pQ3p^Le$?rMud6Rbxz!-yG7bz2z$^USP5(;udf(gfQ zG~f68y^)EvcNWp#bUoDt2=h+^%o-?-|mo~iieWqLNP<0m@2PTB7ftyb= z@H`K$>v9Pr5X`L|rw&CEN2(9SB7A2SE;d|j9@*F}sd(@*2l|P*fWfK>1drZUrtUA7 zNXO~pKn1cjf~~TLbje1g>EPPzN2GH#UIBxJ{}S9=E`{zs-w#hO?vcH+hJxroI5v?j zD!4lP0WXq8zUx3RAP@|Gq$}6wXCjFLZY^YSWBxN9#&g)ro$%5}aYn#y=tJ_aIT%4d z5d4u`rlp!};XGmbZkJE*kYJoi&N0pd*yxY{0${xD;;Q1h^8f$<07*qoM6N<$f(}t7 Ae*gdg literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_code.png b/base/resources.pk3dir/gfx/icon16/page_white_code.png new file mode 100644 index 0000000000000000000000000000000000000000..0c76bd1297751b66230f74719504b2adb02b1615 GIT binary patch literal 603 zcmV-h0;K(kP)^~*-1fljz_B$LUvK}k?BNXe#Y!m=zM!!V#}8bncK5m;8VP zw86G*RI63?Cd%b9bX|ueNlZ|wR6rj|r_)VIP@r2imh3?SN+^{|kY%~8B{maJ@F*OK z&VH9LwOeGt#DRjj0~v~8`>iO7!Ybi;zE$va`A^T#yW`y44;k^#O~K5*jD=qcUhPSc zvyy~q;5H_1WT1l~cqje9yfa+l!hu6xjdOJ8s;8E^+=QQ$tw p?%p!Hy#YapB=@+^9(46X{{RQg%9y;OKjr`c002ovPDHLkV1g7l326WT literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_code_red.png b/base/resources.pk3dir/gfx/icon16/page_white_code_red.png new file mode 100644 index 0000000000000000000000000000000000000000..87a69145075afd8f8fd8b391c5da1249ec8b2889 GIT binary patch literal 587 zcmV-R0<`^!P)LWh{^|hy<@Q*xw+qo|KpY<+vaXbbW{L4q( zTsjXEJvb}e%bgb=o%W0h?4u1;^bWTqH8}5Th002ovPDHLkV1nrS0P+9; literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_coldfusion.png b/base/resources.pk3dir/gfx/icon16/page_white_coldfusion.png new file mode 100644 index 0000000000000000000000000000000000000000..c66011fb0fbdcbf210483d676b7131542a0e282b GIT binary patch literal 592 zcmV-W0k7R5;6x zlV4BMP#DI+Z{WQcKZBTk0lfkj5F$ztWhP#lcuyb@0@rA^#Kpu5KLA&Rgc}o#aSmis zrZC__xY^&#cI&!!{c|4Q_tcec*#b>|Y15wPcY2=o3;-Bl=(t4;6Ok*pL)-{*A;GX^ zS(@WGp6j~k1wBVR9)BB_gar`}HyRBXh7nM!)u5^>N~MyN6bc0-5{W?44iB<`2biXb zR;wk?jIQg@G!5l)SqhrXCU}x$GU-dY1sra}0uCq@153FUULT=jNwSk}0WBjKz}Jdu z<5gB*<^XtpAmp3m^ZEXQZWd1krhft}CoYaF4cSMvTJ01}X3X37KYdx-D0$c{doUe8 ztY{vlGr-e*;N!WAV%_hgUawyYrhegW>^F)pv%uUTFslHn; zvJ)l{%w(~{!O4`KTmK{Q{zCYltLfs&4?nz|6IdlqHCvX;|HGv~!QW?8P~_d#e0$v$ z)5XHEz{3>qMiH`1+qNYf?huS+@L`J9_$cjJF)Hf?@pu;)`9}BXwGUM{2!{y-4|Z{L zG>z?O%Cp8P5T#j1DID7u_*(Jg?7iss8AZQ+&;u_J{FmILf((9eoiL5nGUe>Fgq*U$z0000 zJ3A|*qoWOonz+4ZQ0KNhDB07SX1?#FrNy8%K)_l}y&kh`*KYdy`Y99&tgNgMLSSrc z?B?+B@HO@P-jS~z2Rgc6yy~Y~%>oJpBxsb$5<&nRLqiuR7K=@0SZj~jTs|sv_jWVX zGe?WflejOaq|Vec=s9+ahmXbyJ|T)Sl*?s82sr2H?Ce~HD5WI+Sz&tmWrN()wI2}+ zKqg92t*l^-#ae~;9%KFlWkmwnY=-UK`_|%ICZ#P1gdjK<2n38VXsuC7{WiU!fZFmm zW~Sda9(Qi@pxO}$ARY+;t##Ao27usOqNt7Hwq6K7G1il@xitj=LIM&{N&#SuX;x4x zmG6FhCg-$PI;hQ=;1iZ>F>^~@)IPi;l}fX?SZ!QiO=X<|pSVkNpJuLHzW(FT_~W-v z?vFpkyE>8ee4d=7wKauH5~dd_M7d2Aa=ICC{Nj7Blqv&DQEP#j_VeWV&WXL>c=LLK zsmYg^_JiDb;%U!UxO%qjFAvsDFj-kzT2$GbV(ZopPM$i$z`!7jvEk07BcC=6FMt4` z*0u3Sy`0b~%#(0000K literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_copy.png b/base/resources.pk3dir/gfx/icon16/page_white_copy.png new file mode 100644 index 0000000000000000000000000000000000000000..a9f31a278e17993d8d4e13beac2f9d5f7b42d08f GIT binary patch literal 309 zcmV-50m}Y~P)sF~CC`eaI+m%Y8jfzomMvZQaNUIT3LIrJ$h)_W{ zwF|LDNlB-g`Hb_G$;>3F$9JF3WYR|3fy2C+_wH}*xp!_4fF2UN4lt#d26oXwru}hT z0+0%Vz-l&|Tdh_L-Ng1G2*RBtBncRx;99K)&+}s0whhxXp{go}$g&Jk6k|vfypI5M z!1sNGVaV?!*L7i87Bo%cfO@?S`bajL{R<($@$|PtgBRcCGIJ_2a|&kO>G-s2aR3E4 zjssoScUa;zIdOeGHBnH13G)W-zt$kUQgNfG;96b=v&4NzRt&@7nN%v3HsG`<<+F$cumMs448N!W3r&2Z*b~D5^$^d6Jxn@SFK5Q8*uKSR7x{I|H-_N1f+AD zSYC5@2K4OKL$==F9U@CH;ONNL(W}oZICHn;d?~pw?GRIsH*x-68Oy6SuK`)`{E)46 z9^3(-HXa#X89SBv?u_YP)WjsQrp;}0X?Bxrvf12IKW8>3t`e~W9|JS<{btTNbNT@EQIWBSNJTX8AMGXD z-SsH|s#>j9Xf~VMtyT-YMD}5^SWHTY5->o`k|d#AE_YQd79j`%GMS7FNvG3b7^Vy9 zn0HYCJy5MyQLoqKnW|JOp-?D*<2V^msZ>BOv0ANd2n7t@{=V;sZrQ>3c})5_%ms4z z7!qXwHHe~!QFj8aR~&*-3F?O|;#(ESIXP~Os%|~y^7c15*q5`gz2-5ol!fU92NIGT z_ves+>+Tf3gfcL?!nimYmR}cw*|BGULzI^7!;k#3K^YO#;!+vM@N~(99+<;fdqr zYPJm+pXYFYk;neQyXXEcTQDNQx57i`Okp9A#n?<7!{#tnKJdsF>utb@JH7dU01gfL zEK2hoPZAnO5+je3&^i*hWM`qCW^vLK!O*?U-#IvXV?#6koWqrwnD{j&K`7N>^tR3G z8zr1(qVOzcF#nF1&0MZ5C$l8*E^Uth0000zE0Ay_3@1Z_7#f-XWL#E{8Al7>L$ z0Rx7lnddoqAyfT%&#`$;v0@*5YdW3w z7mLNoa=FAshK% zDiy@zakyMAxr-H?iQDZi^!t5;Eno2A=?>mMx`Vg(Z!?<53LHLvfTPa`$mjDcX*Qdv zR;ylN4OH+m)fVX&Z#yZpUae;ss@a$K&})gHovkhr@w#xyPVlfVgXti1_357y%I-UHDvRWYvPEX+#g+j4Q9ayba zh7uQN1j%HQgA=Fp9DfODAU^*3*FCs^6IpO7xg`RUXyP)(;=d!ly=#I^l3e0Cub`{H Z`5PU3+D2e&<<>s`J(VpX#y^kqzQ;#=2x({YMw9Q&ndHT&`BD$#%Ql?{+)-OuSA`r}MWJ zVg+2Gc(GW}a=BERPNy^;kEz$|38dTYlFQ{%5S!g@|8f8D_!Nu9_Ni2glF1}xG8xi! zorc39&F6EPOeWOt_XS`W2H_Bo$MXugy}SEctJQj=(TLXTHL(jRXfzs>NF=0SHk;94 zF!&HjdZNX(3U3;LY64IMX__Xv%_wjLC!J2`0Jw?X=zPK$C$`&dYPDKaC={e16bcE@ zgun^<0k;ak*=xLE)@(Lqu~MmsFoMCLY&0Qog`NO(h@kyxaA%EbwJLy8sU*Vi`~52K zX0wrqW;_LmMq@evX4iAM9Od(Q0eHP$1%L|xAh@vrqB`HPQLon}f3aAka=9!3hr=O- z5F9`#J_7Jhah=U(4RjaRhkS4Xkk98kDz-`i!r|~~AQ1TFcDw(@<8g{aBE)l)PNxNE zI(RPyc>9e{@WGSMU%i7*v{!&P$WLz25)0oc=Dl-yy%xYZAm4b-rttL7UjR#%`#j_F R;_m(?iiXTHIMmcoLoO94I8;j@ zv^2DJ5#orqydFJX|Gm$_Bi_vyew+j6{r}$Qc@D1%fQqeAhJj)1!z4pP83k2MV2~s! zSt^w(<#HLFVBg_#xz1W8ioi(WY&Hu~6zil?DI^jJgu`K35(hkP)H%@Imesbg#5!Ps_$Ni*SiR8&sKb9?M`0-mH)gtg&YgRX#*TXz@Z+| z;|2H@xzE0TfuORhuO2k6#K8#sW^J`mQ0+E@$K`QkFV+DTlI$w{GJ;zid{*v9xeIe_ z$|Bp`@iKkgoFK3{4Z)#DWKV~W4K@5WZN+Ql_7%YxNqSx7%cWud&cX>)_PvD*UzxZg a%Kia9Rjz_59@~-t0000)l$0ECbfb-0$}>7z|u>IvuoHEmW&j4lzv=KA+EpIObc7e7{sGA)QVmnM@*^ z%|h38^m;wC+ilpk%>l#V5LCqP_y2_Cayd^XlX;j*r54R*lW!zbqtSpQNyz8(JVmWm zyV4S$2{Uhyc{Cb0QQbf{ZGT{Kr zvJi{K_&f+q^Pv4MK$hhS4TgFj_FD*rLOePdE-E^T7ZzTFCRUB`*?9&h(a#C!-v8lWG#k3AOJQaUey6Oasked^kDPe=Khg@7s584 zg`XfS1)&u*_c;I76#%`kkBfiZgKKo@0)9d6vZw=ExQUtV?eW{Y1Xv}=4X(2zy85d> Y0C^(qLv?Ui{{R3007*qoM6N<$f-gW7od5s; literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_edit.png b/base/resources.pk3dir/gfx/icon16/page_white_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..b93e77600def75c9a144d3d0a5088a62c02cbb0b GIT binary patch literal 618 zcmV-w0+s!VP)$>5Y&axjp2O=VLu>*f>1L;s0)kkvKC!*u?s6CVL=HJ6oP~pNfZc; zsKr=bq;7MITw8NXw{SZm%59TId2x_9BQ zV86`NuvGI!>o^V!Na!=$7GJE{Cq`b+XwknM{UcGHFTTfmuS+ zm-zYC!P3+zmY;SG$?!fYkOih`QYaLxyF}A86h$GGN}kFj)_o*0e zjPMP%zTG7FYMAfO2Nn1D`D0Cj?Wl>5q%@CE10nX)KxpNmwk+!IWkzywiYD( zqUXiYYIq3qcRyMGJ;IY`(Gz~E$J$zu2+R{)xGlE*88b3WK6V*J>}2iPY1HH|tER0W z_+^^FdppY?o)Gt5M2`%xwRDH@R3G}^i1l4|6uchm0X0f!@&YdVLB5K&dd7Rv{)DXX zt^&vP;}kqj3f>94j+4xd93>s|Q!Ezi>?r8(Il$P}PFxSqu{d*!Y%*#cX(R0f|Juz# z3o0_xI14Al->1uky@W-rCI_%l&>PK^TXNSN{byMk2AI5vbwp!K-%-@!-vPR3iikL1L7HA!^!~ChCFU#lnGzp88=I z67V8PHBo4(l$u?-AKmT8?#_0rKW9dUNRbpLc`}piywAM9$xZ-3fR1C75T(BjCn-l* zjUcci2oXXo-}iqun@#)+`W@kL_-U&|2>MxZy~3IdmRm&8b)9!2%ksg3R)nNnT*TJOC=6{2hG86Dz+<^p6qfG5$i^UNUh+u)CD7O2 zK>Ioazn;U|+X0x$=feveYZL1W*Fm%e5P1sajd#eW#^5(ddx76*pt$^)b}$Q4oPabL zLc^HF>Z{8za;f$LtN0P$6C?1{X*jtXkRJ8IEeyiSzencvH3Ux_y>y^}wfJrRCQN#9 z?&e+C>sSAfrE%mZD5RfZ`gSndD)=P?+nG5Oq$zmY&-v+gc7R6c0u8^Ke#|XOq?gF@othF3zFpM8Il<8BJrWqBtF>b#_ye4{0)Xbu6j&@UIhRE002ov JPDHLkV1nWI9dZBw literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_excel.png b/base/resources.pk3dir/gfx/icon16/page_white_excel.png new file mode 100644 index 0000000000000000000000000000000000000000..b977d7e52e2446ea01201c5c7209ac3a05f12c9f GIT binary patch literal 663 zcmV;I0%-k-P)^@R5;6x zlTS!gQ5431_q{u#M2 zg&W%y6a}>qj1Z|7Vu&-DW6d~k-n;jnHsjb-q#u0C^W!_5^C=MlKq<8oNCQ6qS00!X z5eI;XP=g!^f}j{hku}E1zZ?XCjE;`p19k(Rh%^AQQ54xysU+ocx$c#f61Z4HnT#3u~FR(3>BnZniMIF4DouI8Hi4u>cAK%EN)5PO(ip3(% zIgBx+QYirR){Z8QwV$9Z(Mpt=L-Or3#bf-G@66}txq0yc*T(zNTBDT0T8rO^JeNbSI-Tzf5!pBioy4NwAN^?iN#{;fH1Jke4Xa`^fR8m z%h6dq%xX)S?7`zae))(Xst^Scp6B8FejQW?RLTM8@0=vnnntuRGBM2dpo>gbCnTD= z^<;=JuqdSf@O>Z8^XdR?s+KEfhDdB_#ahFj^giCtzT(s8kA$AViyTqaAR;KGaLzUU z<=GqA4bRwpX|IG~*x>pZ!@zLr`XQ`od>m(`;jz|M_*1GDO#$7;n74ppb8=eiqh760 x0yt}J1#p`gw$`o!R{d7zU9~!Un@nJV{4bstt4Au+Up@c;002ovPDHLkV1kWhGjjj{ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_find.png b/base/resources.pk3dir/gfx/icon16/page_white_find.png new file mode 100644 index 0000000000000000000000000000000000000000..581843637079359a6a58fcdccf0763690c67b063 GIT binary patch literal 676 zcmV;V0$crwP)_k3`4d{s8lK_6bi^@vq&To98fNoK}7)fx$e2^Y&@<^jR_Ee+8}KG;X`@ z@bCyiolqX>bb1ZIs%QGnjzFU~L8H~d?e;*XP(h(S262}XyZ3a0h07r{KV?E70l+e- zE`%3x|M5#q+;HOC(h@A^M)7Rn13dm0&>K$j%k_F4wOWlsNCIH+!c_#{eS&TL8v4yc zcpnPEY`cQzZ$ILq{U-MA6Z6Z|1p!FZjQ}tXSb25J@HphEqX-6Hqo?-_Zn@{d#>2Ml zJGhxTAd&emK$lV-QK&VM&ix0Xy{GyS3Wp(+E1^8BhD3T0a)m-Lw@Lu4zQRrP)9(3F z^>$hh@N>OAXrmPYunLi|fJ$_*5i`46;M>~*5D{bp>-OL3{+!MJa`3kv~Q#QfQ%c z)1s}QE<_XaYBG;IuRF=td#+}fi4h(6HgoUyJLi0t(*dA^B)%@8kkG&bdM5P5^Z5WF z%d%>m^SbN0XeV)wbUOXn5Ag#A$gJx+7-OCkMM1S%MWIlTkbFLmOeW(&n&wUd&;`>p zVcRy$Z{K0=?SpNnP^;BYEEXleFbq(UY&LrXX$6qkJ~)8+b{=jj3HEXds;Z(?D%}}L zX3`39&dy=Zyar!ehA}e>w)(*vrCct{PI9^2Jpj&OZS8<3-@{0(gNv%1{)zAiLY+_^ zl}e>Ofd4&#Irj#7>=o=Uhv5IJ@?sN0^J|(WL2Uun$4}si6}TG-s3T#p&6GE<<2W)O zf{^Y2HlO#*QDvTp3v&d@;8*}aUC4lisG9(w7@d5Y8y)}U#FwCkqp*Mcgme4{&gGRf zlBfd`nF9cQBKB2_L{F8G2)7pAf$i)Ds`|}-c>pc^LRW{w4SQ)3N^BbZx)6BlCZts! zKph%`(m#xg-q3I7=(us;9<)*2%iuQ1J`oV3gU6V~T}^JU5714JN33&GwEEru0d}Uo U{MPL+lmGw#07*qoM6N<$f^vibe*gdg literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_freehand.png b/base/resources.pk3dir/gfx/icon16/page_white_freehand.png new file mode 100644 index 0000000000000000000000000000000000000000..8d719df5205f7415ce657e5c277db4533c82f346 GIT binary patch literal 639 zcmV-_0)YLAP)p{{sC7)XB-g4w*W1a1)XtvxrMYa1o?wn&v~3 zHnC|#(>B_M1d`_7gfzLiHy=0c<2kQQdXu*33(xYN_xYW39(cz9jEVT%VokB8|DoF~ z8u%Q5sdl@4VB7X#uh+v_;yOGY&pRi?378ghv)P1cngiAAb<}D#l*?rWDV0j_dc6Zk z-|P~AJZQCA=yWcQjG8fYnimzj*3KqTfN0Cy!G^$7)+bQ$+mHVd1J zvwOR^5Lm<|R+uyB1Nu4vL?d4qa3tn?9H7SZH@~u=fFHEDfSH|bHU6kh0O3%cLdyny z{`9S2Sw~WMy0MPy!64i`jdk4Z3>^+KIL_fN2V_d&ywBt`^IJpxUI$=YAph~5`;xCe Z{s%Y0vkUXDnO6V+002ovPDHLkV1loX8z=w( literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_gear.png b/base/resources.pk3dir/gfx/icon16/page_white_gear.png new file mode 100644 index 0000000000000000000000000000000000000000..106f5aa3611a4807ec8c21701c631730275089a4 GIT binary patch literal 402 zcmV;D0d4+?P)<@FR}JvtGRKa0_WfK^c7uXaFH3q@Y!Hnl8VySc`OtkPN3;#l*y*l23+99h*9JzA00}rAC!#M1dZ#v9YOBH|eC*${MmzzYjBu!!-< zK8tujf&(6i)1biy*F>4{f*Kd(IU-JsG&#b_@NgTnx@40)2@2%c;*=?-2Za=}O}7&( w%_K#(S>e1j&gfY?mR})n>>0+8p`iTe2d1K2h8#$+)&Kwi07*qoM6N<$f(2cptN;K2 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_get.png b/base/resources.pk3dir/gfx/icon16/page_white_get.png new file mode 100644 index 0000000000000000000000000000000000000000..e4a1ecba1b60e54f3777717ed105cdde745b7184 GIT binary patch literal 516 zcmV+f0{i`mP)o)wchR-92qq~y6`XqbKmElbB3z{pkZs0VPF`CFvS?7jDn^mFo>d9Y&06* z&1MsS!M-CH3ee+h_sy)Ms%B*ec3R0RpVi9?*mU84yoq(Bw8 z<4(999dJJE!V%pWT~HGRIAb;(#O%2K3?uRpz}AfgE8e9q&OSdr^e^}lC$QXZz;S2A z)w>^oHy>?v)q--`!pmuBe96PxP0u*inQvyFW(llfv9 zXV1s*Jh`y2H%B3ZTA(AzpsQ?hb6_PyZ=c1?_B4fbl>G%!@ubJln=!)x0000#DY{xaiib^#X=YT4@yE_&2#eBulEdzjE`u&@G%2(&u{J-<}d(^uY4W_kMfEX z@!X)AR9F&FL?RJyJRUzvBoeqN{5kY`z3wcM0+du73~_0|*lac! z42Dw(Eg1o{Ash}P8jXrqN+1w`*XxDD;ShmPCZC7#4;wWbHoMvBl$=zF-`?*9j*Nbjd=v@OWt_BgKxP-3wd zy37?ATx&$b+&zRM!K;BD%Okw`Sb@&Pak8$KRX19jWZmC0&n*Ggv%j8nvSPDFw zEkV65AGOoBQ8kf`R|}Px*&INNS%osq9b{Fq2I(x6@xM>tg=vRLF?I`0rWzHyRc>}g~)F_Qn`A>)C_iwK%Z zrIJ;xR)UI1Y4Ozts|-Nho;q zVk9-bX)%F~!;63iu$Fk=VJn3~fmb5S@@)ZqjBT2{f`vT`b2}zxb0$o;EF@G3&BHK^ zc)`1kUzo^Qkk$?KFKHNBD?nP-MJ3b@&4fg;g5l2wMi^g?9qj+~@b;62o_U1_S1J`g z7m^UMg25FX1MJ5AQxAJ5F5WDt=$=-@JV-!LHA2vuxl9kN>PS8x??^AINH6LjF*#nbk4}=n3gfWp$kEX5IpHS zYiQ{@d7Nl&d$#+7-TckP&Q}N91e-C#5QQ<|d}62BjvZR2H60wE-&H<>}%WqH(_V;zPbB1rgSSSC(0? zWlQ#?N3UgnJ9m2C29w!SwoOo5_2Iq!<8vCyEoDoj@#oV($oJEg6Bj@;nD|2g8 s%L|>IZ381yx9RvPhV4J)*SeoEV4lyr#k*`nfWBbxboFyt=akR{0DpOPi2wiq literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_key.png b/base/resources.pk3dir/gfx/icon16/page_white_key.png new file mode 100644 index 0000000000000000000000000000000000000000..d61648452284da1bc28b10385f95b5d2bf027901 GIT binary patch literal 616 zcmV-u0+;=XP)-tZUVHjYHp;RjQ0M0pRlXN=mLv{hk9Ebp9&~+Wj-T9IkpzWPWd#fZ)d=zV^~S`;LE*!&u-?g42^wwN&Xr1~#d5ifl_2*B1OoS}CDno^8a50ArfE8;stQF>AP54J@H~%T zFz84s;dO!QJKD36(~!QOg!t_^gfFcSKDU4yK0+Ypg$NT^mIYcQ6bk*3P(lBLh7Df_ zTu=2xC#+-_%)|{Cv8zz0t|0y4D5M`xAc{gwOKc`ou<*&VjUREFHs1qd<_xSkKeTBt zgyCi=@jj;&Ns^GsWWaIUl0Y2azcDlF@u{(P*!+EH;lnU~b|Lv{4|4Hdkh!qoQHiE$ zY#y>KFA0QEw=4Z|uV{0A^`Y=D}hB$GP&<$bi8q(u;p^0(my3Rz7fP}|# zGZ&#uor4@c3q9r|f?H6-UZmfgKx(iV(MQ`MPWB>iC~SxnN5H*zb*A3#zWwgu&c|}3 zn^g87H{pdeasl%Lhmab&jC?lES}7C?4BFDNA<}20hoY@w_IU%i*T;}}wh!589}7~7 z#Ug`-R~4j&+K_y4kW@X7qLr-)S5qVKU)tO;+kXJ++{vPI@{hVK|PhMVVx_`)vx~zUs}c9O-Ok{00000NkvXXu0mjf DS5_-g literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_link.png b/base/resources.pk3dir/gfx/icon16/page_white_link.png new file mode 100644 index 0000000000000000000000000000000000000000..bf7bd1c9bfd78d689c73ba67cf914182933ee68c GIT binary patch literal 614 zcmV-s0-61ZP)OOAS;jTeL{ZSdz-%)SMH9tDF;N4B6%j=d15J&5qy`F#vB?Ar zqS1nH@%ny_XSI*Y>) z1f5QYdmzT>YciP<3WehS<{GovEaLGv27>{*-7f0&I$yJ^L%ZGPv1YT$V|u;*+ZCWz ztHI~CDVsuy($SfR6-`N~K?9GTB#l%%0h7 z-q`K-y~E)+s8lMyTrPL8^_pUo)9G|SluG5pPqw6!LJB_PzyJUM07*qoM6N<$f^=yZ AYybcN literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_magnify.png b/base/resources.pk3dir/gfx/icon16/page_white_magnify.png new file mode 100644 index 0000000000000000000000000000000000000000..f6b74cc40f82fc83e4dfa6e9647ccc1b34e6ed7e GIT binary patch literal 554 zcmV+_0@eMAP)Vb2f>2}Fa82O3m(Ob=t*sniin`NpInLyMJgI`saru@YOPfh zy4g0#G*cV!#N%;Gq9_VH9?v%kjS3Rb1j8^;C={$Gp=lbj z*(?%?geA!5^Pok%UauwjA)v4g2`HedDw4_Mk4hhBQt?e7YJ5(hcj|3dNu^TOPGnjB zTTsqd3GIZ=Bb`n=7no)dflv&K(lsWw?lH6T1Yht0F9qgIuzh}ym0%n<3d3EBWB*pg z+G!I0lbAEXyd>k|QNuwr4=KX1D+tLPv)j@C1=N4sA4NF9A>HcO3G47*Y6!+SrUH-7 z1hb;^#S=r|`aMh>J#dWruAEf}gcR(DRUC`ZUev&$Sbh0SgLiTXeeHEU<$_YV;9281 zym`igIE%Sm8DpDw7@71Tv^EB5xSdUR*0$Mqp+Wq8OoaZtOg52&)zZ;;M=7#C1Yd6x svjx>8ad4e2x|*xHHwRjcjs6zA0XLDUqKT6dS^xk507*qoM6N<$f*wetruo^Ag2=LamM1T#~4RmC^m`_ zs}H7d&XJ}mg+hU?tu0noRvyjI&o2SRAeYZFesYkts79I^jJ7!A7%6nJwq8O?iT55M z1OQ` zbL{!Cp5o*IRmE9PInMCSPjTwfT~J+EYkz}tjxY=fg5Yf6EQ@DG$0kMJ9h^&$W}9BU zP1oj2;?MWVkKIEl)r=Y;L^Cx2q|>!)qJJ8zE7-V*-Cf7V8_2#1c0N975t~+&QUpQJ z5(uo(-O_`%Rj@U@t>JYAgd!>L?0Idxtd#oW2gc!jinsAEva8|kF4#Ic**mmml_{d^$s}Q5Q)KCys4sfck5bP1SyeHwh2`A<@N&t2j0^lgHC_^(pAAPCNjwl+>AN%C4Ll>_8Hjda%9 oS~i=#*e)>KsPlg0=2)Qg6BCqJ=F8HdGXMYp07*qoM6N<$f@i)wr~m)} literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_office.png b/base/resources.pk3dir/gfx/icon16/page_white_office.png new file mode 100644 index 0000000000000000000000000000000000000000..a65bcb3e1e9613cd9e4950850db43d7025a5fdf9 GIT binary patch literal 779 zcmV+m1N8ifP)JNR5;6x zll@CmQ5eTZ^k*a#RQf}fVOdd`5NJh6S(>6Cf$wEW#f&JyAR#GAn9>Gml;nOf3WCDa z5({5&UB$(IF?G#$x4X@Ickg!Y-HU!Z_rzX=qAq-XI_LS^=lOCT0|0{#{kBkYDS7{3 zD`iu%E=`cDX_^#^#n$5SIQ|4Zhsk8>N|zXHXG@*41$i-7`Jr{8`3S_OEcmY|RF48wXkk?WpdVM4OePBSbfh z#4_=eXJg@3epx~gi>QbUmO}Bm(ENN3+@c?jWiKvSrm(o|W}Ud*?vy~fn1!V~Cl4kB zI-;c!8f~-v)jX82%EG($>?;KSD$64f2&4qQ#=Yyrcpy$57RAVuV#vKMP)0hT$r6m# zc^F^XaJ8R9Q|}x^NoJYIvYZkq-z}Tnj@UJK2l2H zG}p+VvtjP2Z%bsb$~7QLJ9#pC0dKi`ppOd^_V;ME6tdzC0PtV|r=@e@37O`%0k^=5^`%cf$eu00N17Ro!{^30krz>a%3j34C?*{Mt2^a4~ zK=P+Qq%|f;Tc&+9ps;@Mw`EE%rgs&#y=j6BUGg96oIqdwj9-fiy*N(|@o)eD002ov JPDHLkV1j#pUPb@_ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_paint.png b/base/resources.pk3dir/gfx/icon16/page_white_paint.png new file mode 100644 index 0000000000000000000000000000000000000000..23a37b891c2f5faa3b8128d45373ceab794ca609 GIT binary patch literal 688 zcmV;h0#E&kP)PK^TXt2QS_@2qt2T|9~baC-vaPn=ziepcfAwB$0!O2Q)E}1e8!q+9)KT5JVKU z7HNY}h##OS-BxWHWjD0wrPDeEfUClHs%Q6&2u@FTOJkKMQN|_Rlw6rQz$gPzqGNtj z#ruSeFeh835JJFiM6vp@6M5bXj%k7CMt%SIwfbF_fD-3*Os`9Ly_Q3WQ_SX33E{pX z9_WIeeTCGQ3wYALpBcK+P-iuw;3i&7xCua37k5# z`>c`M@sGeC7cdsdz`aE9lOz!hPholbyz%T85LYf6O*@SA+9&+^7k>+4M8$A8iNQq{ zQvn8k?-+dU`Z@gK0z$EtPV#+`^OH`R@cE-cuE&_!D)SZGxmQxeobP_Zwq zMEgi6ePN45N`|V1so0uE8^}1xw8s;VM%Ai@7} z2-&Cyvez_-O4?6uv{zTaj|YeYEk34i~K@`8YW2g{x* zc;7z3lItpVy_et{Z-ZZ)<@*%{l7Ao8mu@V7*gz<_1##mwW*%LEwCdzNsVLYx2*T-J z#HeQ*_a=R~KDdVNk$EVgAIRl$oQi_(`_IrdJciDpH|Xe{K-YsMtc!cRnFi$qzsr4z z5*$;ecov%3->1{YNy6-Gf(Ecy&_I$CjI#laeuE+S120^|Vjsf)W&i*H07*qoM6N<$ Ef)^4A_ab^avY?n0hpS-#mn_4{O$e%cm-@NH=3`90Wq+3`~HKArSdfX`&Z12 z(CY$VW-MNtXX4xy%yUeE?}*~0-|iByA@ZrwXgph4S*bhcc5{HB!DFVm_v}P*g7+Q~K}7K0lcp(^N@X>U zV`{ZpeIf${R6Hgg4FL^`X$Eu75k(PE6ycl$AW0Ic)#@rR7Z(7;V?i-dR1K935Jgcx zPfkwK>2wGokf!Nih^ARp6-6arYFG#(9Ta!x93nFEjoA==z(g?#sDg?Owk?Mg7K+>l zWYsf(<`#+$h9Sp6gFOg_dd+80SkUpk&xM7h0`Sov9W73spU;GP073|VfZ&Gd$J$*0<~TV5aPS|qWH57|VJz+d0000vYep8SaFV10Q$h+;hIUPX_=v5b}%>Tm<(&j1&5;I!55C)oN0s(P%ZB zP3Q#ahfpXKWF@S?jm4U#fv)QovMhrriclyNs6-G12#3R##4PSZ0VY(dRWJ;Lwuq{# zAW0Gwi$yA^R4RZ!;W+L`f&%x{=D^VK#BBWL4Ys{;*!A7Q;!=dN<&D8*GzGaF4`hV4 zDbY0{NrMX>ZqF=0((gR5-zL$kC*b)!fwu{Euru|XrG<$^n#@)7i_>rCmRxnDq>$Y%gJaCkRd|tE*a2x05Pe!I^e13o69#&RQZ36s0 zB=O|K2Yi(jsMqThn}9t?f5E-)L^naZ+db$&%M$!bCdm=jv7?t_lB?3&%Ltq(>ESw? c;MI421LCcoDG!2@;{X5v07*qoM6N<$f`UZt7XSbN literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_picture.png b/base/resources.pk3dir/gfx/icon16/page_white_picture.png new file mode 100644 index 0000000000000000000000000000000000000000..134b6693687b2fa5fe36d48a9c0b8001f937c741 GIT binary patch literal 650 zcmV;50(Jd~P)VHAd+bMNh~)LLRqN>D)-jd9UvB%+hyKX5U|&4t0)fzgD-MPpQ$nHU%yoz=vI zMGb>1Xu!6Hw$NT~@Au<4P-+{9;Uw?&oj31uzH>xX0T7Xkz!(tn|Ed9-s_FqyReC13 z(ll)vW1O{Ck5ihay12Ob2ABc@RUI;zHpaMiyRDs0r>|D4rHw{ItJSJnYjt~jTbGuW z`X(~}?!&86q40R8<4zYw;$qi0^3ec=c&<&H;r`8W%H=Xymf^i;Wo6~<+}zx2UMzpC z*6MZN?(FMv`n|KO3(KFiUaucP0;Z!@LcUNa%8#vGK5aZ>wDgB0Gi=t*argWJcdlMQ z2#MpEX0wU+9&0U?N(F#OgpviU_Y{jYMsj65U3|PjwUOY}lUYj?MTiK_Il}NCVx-Eh zDx-TzMk7se+M#W_>?A1-x}ZXw3kkyz5kW)_hkjsi@RhKadN#H$Hq)$07*qoM6N<$f}lhwPXGV_ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_powerpoint.png b/base/resources.pk3dir/gfx/icon16/page_white_powerpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..c4eff0387d5888c638ba09473ba6d2369f7b56f0 GIT binary patch literal 588 zcmV-S0<-;zP)HU2HvUSp%6 z*n}iP63IK?dpo;h@sj9~pcxo;VVTc-XLiP@DgefqE#NE=@oyUd-&HjLpsLIuSFXV-EMck)oQ(A`s%*^&wf0(rNiNHsU%=0Rw;WC z(kbc37l6fo`-0uR!pYkYv8U^3?nsh^@pw!K0TH3uYyx1_2>|JbXPmfskJ|1YAw9w! z9`N)1^Aesr;y5Nr5-ODn)oOL|CGi}f9!&iVwpK$khlIX10X$H6^A_stBJqvLhU$?V`QXqKme*s~gVDJ4A;LTs_e15jhc1;By a82kqHEPVYFAD2!50000JNR5;6( zlS@kiVHAe7MZY2;Xi-5)WxDDgv@tCUl*&p14T@Z~3ThM5LP4tuQfLu@EnG;nXc<8S z6&3BN?fx-cv-Kp6>HRiNTHE>$X( zD&=w+?GWC>?RLAGC6Yix;an~UmSt)tSf}1VS6N1N2ONORdD? zaj}w6DAZZdOud9Ep?M?{iQWbE5^9HLLZZF|1kdy0Tu4InEuboP9@nvbZ-P0n4AZTy zyMRIxRDmUE#LdqYuD=-Qz4N^bC`_#S7vcLn1M}{J(Wl3#c4VWczu&)AjUlh(11>gp>f`wv{KnjF%!aA*Jk N002ovPDHLkV1kkt*XsZP literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_ruby.png b/base/resources.pk3dir/gfx/icon16/page_white_ruby.png new file mode 100644 index 0000000000000000000000000000000000000000..f59b7c4365fa1720af1aa04eb47167ddaa6eeed4 GIT binary patch literal 626 zcmV-&0*(ENP)ZS(e|#C2>JN4>y}l*tQ*E7zP@R2CCJnkW?xa6bgk%(hgtZ z0=~d?U3i`+Mvi4!&~+WPT1^NX#{u6&QIx+DE(oR{&T5&-ovF?@wGw)P&AtpHZa|G%V*GUUqL@@!d4V$`8=##4)ytY959JG zdc&Kho)&AL70^i z!PEmeeDWCB-UbK(*4JST44^tV2z_J(dn~+vBMJT97_7rzFio=~XczIv?PQ5$v%u~y zu(bteXb5I1h2zCV{Jc2~V{{yzZipgsP6;k264$*#5q?GzCm|CPa9CKqm4b116h3Pu z?+%Cm52plC8|5P0@igf2GV1KkCfk{Zecu=G@VNrf>s%g9c5D%@cfxVb6$nY`1IW=4 zt10QqSps_2JLp0f3I0j0u>#qA;v!+T))KEbCg|mo3q0pG{OR}p0fPds8+K~d>Hq)$ M07*qoM6N<$g1S2e3jhEB literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_stack.png b/base/resources.pk3dir/gfx/icon16/page_white_stack.png new file mode 100644 index 0000000000000000000000000000000000000000..44084add79b9a0fc3354d16bbd4b4b5ff8095da7 GIT binary patch literal 317 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-$R@9E+gqH(@-qA%AW0|7U8+xDRI z0k`B18}ImRw2g{jTGP$Pmx3yI6F_2s&$|`cJ!i0UN zB3H;=r{#{FwLaNVJ&hZl9+MTHGx1T^-A=Q0?hRb#8a~x50X%;`b6ik3cw=#XdxWy= zgrpBoDjpwP&g9<9h3x!k_B!?vuTJVkmIJ-U N;OXk;vd$@?2>|rNdMN+^ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_star.png b/base/resources.pk3dir/gfx/icon16/page_white_star.png new file mode 100644 index 0000000000000000000000000000000000000000..3a1441c9a12062a4bb3d706000d3ca14399aebca GIT binary patch literal 565 zcmV-50?Pe~P)SCZIX8XZzY2l?gCw6LlgWJ5Avz#QX4|&mI8LN)w~J1vgL=KLAhlWz*=#m~gyvxa z&;iC6gb?aZvMdXxX`<0+D1hs_pqJ!wxqlEH;CJ)je~uL(gpi@v>!I0f_Kl=E(E+Tq z26na*9gribxx-Oft(HnstyXUUy!39&E-cI%J5Rsy;(PGZH{g{ty!HVC&yGPT3H8x# zw{^gBPW)O0FMoh{k%l<`1a|To_Wl&u&-GXm8izU|&<&utILc4wc6s@u1bmTz6x{qg zTw@7=FQRcg&r`h+gcR$*Jbv+*DPk7v)B@e0o2 z6IlBXW&8xh@9)YKiV~2>+z&XKd24JT55YWz&JtfvCg4r^~bLP79-yS@n$OW00000NkvXXu0mjf DStt2z literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_swoosh.png b/base/resources.pk3dir/gfx/icon16/page_white_swoosh.png new file mode 100644 index 0000000000000000000000000000000000000000..e7708292adabf4821612bfca032cbd019c63180b GIT binary patch literal 634 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 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_width.png b/base/resources.pk3dir/gfx/icon16/page_white_width.png new file mode 100644 index 0000000000000000000000000000000000000000..1eb880947ddf3e745c29e8d9dc90f09c7e6e323c GIT binary patch literal 309 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-$R?&;zfqH(@;q9b3Efq-lM(nr^( z=EYR73-9e)UYMWsXy%?aZsD68Yyv^2$~6QgEcljw%kx>O(f-gQ?@fOOx3A-0+Qw?O zRx~W)kn~Qe2d6f9nMG#g9Q04Mk==M~N!Dglvxk!fgVh#w@ZV$IY1+Xc`d{d2UcaP~ zfWp)_Ivqj}l2SPy^9ZWy6rG9Yx4v67_uA&&9|XA~5-#3)W3%em1peD8RWH^#O%XoM zxMPud%}GTj#~*+7JMxTd!`{^Q+>(D3*|@KV`*G2;{QnANOxu1$r2xIe;OXk;vd$@? F2>@zac~<}c literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_word.png b/base/resources.pk3dir/gfx/icon16/page_white_word.png new file mode 100644 index 0000000000000000000000000000000000000000..ae8ecbf47672a874c0958d0d113a56162c2bd364 GIT binary patch literal 651 zcmV;60(AX}P)hkjP zNW|QGv-YFNLN^qH@tJycPNG5ti6B7;r4mEr#lr@*T8*M85D`{ZR^BWwF23T<%MYIh zdC)S*p=|xk^!~H=+HSZ183~y8v4|mYmZxt&)5{{~>J`>E223Q5>T$=~mtA71q-jdG z+eJhOAyBW^0k9Gk1+rX8)zFx((CG^&tDY>6XaS~Fy!WJON|Gdujg5^~Vzt@o%BcYLiNiTQSD`zL^ociBz_>bDlpw3kriQ@Z`bVsGz-_6N>$&gTDiKDTKR^ z-hB*tHa^>!oD~5TK^0UK5rZ}RBm50Bv}S-yA%s=Ha5RYb{)!z2N&$&64gfhybBu8p lh~_|?8^bu;BRYt{<}Yrwd83Y=s?Goa002ovPDHLkV1l%3CP4rI literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_world.png b/base/resources.pk3dir/gfx/icon16/page_white_world.png new file mode 100644 index 0000000000000000000000000000000000000000..6ed2490ed1432d5d667a76235360824a1088e928 GIT binary patch literal 734 zcmV<40wMj0P)JT{hN;C#tgf#9krG=I>5!<*aE1_(spcgF}<`n4i zJi-}^6UUeU4jUFwdCiVPDm%`Zx^UBa8J(mnR6wEgz^}o8;)M*Y(@l_!Kfv)}4+NuM zaPXE50z)r)9=D=SR|RIqfQ^j}Hu!fzMeQBo+@PZk1G8hOw|vBTvkx`HM)Xe9q3xao z@`p0`NO!2904FHSLA6E@Y-O6zH$DQzvq@aHsz}}<(!v(Z_+EodX%R&NZW75g+nENo zV0020rxE^;7d!067AN>6*+&YLp$9uH6F-=In`XC{Cn%+o|5)b&boEPr02w@|P*oGm QmjD0&07*qoM6N<$g78X0Q~&?~ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_wrench.png b/base/resources.pk3dir/gfx/icon16/page_white_wrench.png new file mode 100644 index 0000000000000000000000000000000000000000..fecadd08afed92536be91ab12d8e37b6bf410d5d GIT binary patch literal 613 zcmV-r0-F7aP)wK%m(L+9IV|s|#(WRl-O^4GvaQsnHq|OstfO zIJ3}3<01}YGARE4m!7=)QisvlHUo!Qymx-@-t*p_129Ko-#pVI)6#!*kLj-AGXWNR zyA_{wKii_amK7^YT-v z6#plaNm#8`-kz@OvjIt^4%IN{@J3bR zRI}ME1Mv85p|%;RK>ViR>APPLB4;;BpCtqE@P+*7!G>I4UjNx~e>r3HA^tWCQ@S)l z{BslcSwL-CxQ&_ZZSv_g0Tu{yi*X){Mt|W7)lbE`SQxFP00000NkvXXu0mjf;)M*S literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/page_white_zip.png b/base/resources.pk3dir/gfx/icon16/page_white_zip.png new file mode 100644 index 0000000000000000000000000000000000000000..fd4bbccdf1643f4ff5022fbc59b82546e259317e GIT binary patch literal 386 zcmV-|0e$|7P)_QM!1S$Bhw4w+iRuFWf;tfR6D%SMJrb+tx zC9R6{2>Ou6#juIy6u(I?|;&Owi$sRB4^20apB5xE2 z#B9XekY66S6lzfCL!eEQRgo0LokTA55@Y#%_wN!TXPw^Q4IIXsG~v#u_4t;x_HM16EQ@QRY+rut&97&UefsPmLrQ5P zBC2kcbux9L%2bJz$P$XV$*zSxb2e@6_3O#;&!FD<&hLjGn%~%en;7)djE^d6!t$lW7GyIOKlQ46hr`Z zjLNuRDP_53dNoN?wd&HMgL^m1DXFU<5dQsrceN>fSz00000)O9XRTN^$%%`*Fg>ryDtc(lF@?b>dE!20r+y z#Q*>(wbV5H`-E4Do={CJp7=ERhw15hgZi)?jRG88 zzVz(5;g?Td1izJyO33bhjg2Qc7FVY@f9!o)Gu?DII~vm-Dc?}3M!fsgjP?F(7`rgg z+xOk8XD)e?Zl=5+un`5!7kr?F=eq)K-5uqr%yU$1hLv){Vlm=)*5~`lwMciiXFu*g z)*Jkz6AF>#zb(Vx`Iv{bdGZHtlW)v(y5k^|xgSUc9%0}S20nrYrO}78ofk?bV!5)4 z=Ngz@+$9N1>>mA%IWx`Fqa240bWkiW;2TZgd8CZS0U}@mknC;!2;wi$eI@`h0y2JS`Eae0CW}q(2(%!m8 zWq$`PDU>LT1_y*bBv#P5<@q0@ttz$hIH}YMDvAigCc=y*)jY-VOpTd;A8@3t7Xh4r z0KTWOk;N2Ox4!&&^4B*no$WtTX!BXB)rg!y8dvGgKBQKLJNXRRp0}Bsjd1|LNQX~c zbC~fjrk2iL@4dYF*vt;}dFn(%h)n_-vzEIHMOKRkdF%3Lq|zBgKm_h>TEq!))nWjq zzn;B!?!(dQcHu$#=JF`cS&W~C`WHFW^B!~MI#k)>1Vk&eQy8P1O`J6V04{D@|7d6^ zyBABnh-d^H0FX&L07M||E0n_dp4v&Q%PSE9p#R#Hq)`5I_(B5CE#q dxjPz0{s-<+c#AC!i7@~G002ovPDHLkV1iPlpuqqD literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/paintbrush.png b/base/resources.pk3dir/gfx/icon16/paintbrush.png new file mode 100644 index 0000000000000000000000000000000000000000..a3ecf87784e7715238421dbbe773a54f602c7fb9 GIT binary patch literal 548 zcmV+<0^9wGP)_f5P$T1}wR3qlt(jG_Y0Zr52WH59esgOQSo5P}VIa-lfSOgY zCZygaE0|WSnkNR-ymix>c|SI-nf-6e(wcueyQTi$-RJ-R;B=$^K+VoLQ)2g$Ws=Pc zm#>>RZ{`29@OSkoJqNN@e;Py`Af1JrY`wEZP%6mtqXSk zPwm?BzjD%=|3xj6wl2t5m&ThH>ZdPV+c10m|F)IK{&%jw_P=uO$^X$kSO5DKE_-is$J8N5P(ZnF4bK|DPP6d6{}iR@dma4U zGwNI63={10?wsg6GrMIz9=9gZKjA|+f3>GAK+D|GJH82pDTdw`PIL|}-E9ldO1tCE zh!Y}h7`H{Mc=~qbQ(FLcAgsD6T*IKskM2jy_-qNlZnsM>1c*c;%G7om9HAYZ4@|gr ze-YdHGL{@3SlraFMS}W1yBeCDwgj)70ffV0WjdWkyAqr__<>5Lf>Nmjzuyn#`-SF| zCD@#CrZM!vJ3OHFTxO9ZIYyfsjRp#Z0 zMwk*D4u?7#jpFF&2#1GEG`Byu|C}hU^-i!wvCE+^rj9RT$?eTa}EEYkR zMK{!HwbGGEfk1HjC$2x=82slTsZ=WU`uaN4eVfe&i9|y3`F!?;Cy|z1E>{~228hLC plE>q<_Zv^tYSsXk%l)sJ)*onV;!t9*YM1~3002ovPDHLkV1n&hO1S_4 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/palette.png b/base/resources.pk3dir/gfx/icon16/palette.png new file mode 100644 index 0000000000000000000000000000000000000000..73c5b3f243d98d089dd9e025edc81b939c1a9320 GIT binary patch literal 856 zcmV-e1E>6nP)PbXFR5;6x zQ`<|^Q5@e>|3Fq06ckj13SKAzrBX7=2LmNa=VjAGbC_kBmo!b(h0(lh&dtlb&FNfD zmuquN(K1t)x?D|-M01+g{cLIqvEiq)K|Q2K51*IA`CQKDe7`gRw4E?o66yPi8&Nn? z6l%~H1nUQ%T@&i^1O5KKw~aW)k2+%HG368DWXx)cVb)1u?vucz;=oXT3q3jhU%Im| z1?(s=#*a)g@)(;l>H@5fX<;>n14d_9M|`nnP-6AN3z#%q4DzF(Nk5nWM_|14<{lEc zYPuy4KilYl*ag-mA8dVe2Tbuq#03kAEX>O@@Lksg>YW6tl(V+B2dCW}0wgkfx|Qv4 z-D>azy5k)pmaZ6BhrO`cMMsS?2x;x!C{kX=N`E6pB`Ii0bgLj_hNq!8%(hX_#U?!j zKiGk=Hh5$0c^KwfGl^?D=47dOtiAw2KNAm$$b9o7%%}<>OK>*QNXr%9w1k|LfQ{U2 zSbTi2+))I}Pzx-B&9LZXSZvF~o2CeGlzvc4uVc3ME*4%1(7-xD(S|uUCaD1_sK#7S ztY9n_un1WWgXlK28Rs!v7K;_~=D2b`P734*5Qt!^h`~~a5OuM~Hfisl25mar^a_}} zg_v*2Bt^;WEyLcAGWiUsw{`FkNI_Ti5|L(1@j^*TA*!PfgVy)tDpxOv#%F0dOfNa0 zdc|1jYs3&aBQ0Zq#{l)Z8sgGaTq&(WaY+Uil^l#q(oh+BaNO|=WH5X?GktSNWOaL* z*ZNp}GN_(f2a)O)VOE@kDJ~t8MZuVBOvi$ni}tLGC}Zpk**1wJva900hs{igrph=+ z+^OPVd@W&MNyEpqoQ;kge+VO-3U?f3JDTsf%0@_u%bjJIsY%3=wv>=dpyM%#>wcRc z+$m+(U9dwMf67h5I&QPOO-M5_z-8e1J$HL#g&=&d>pz$2H|k=JCX$xdMNx#CVVzw7Br$VwirmQyNV@gr)$8lP5a8@sX@X>Dli-1k7mq;##Fp9!vA_9^;^gT9 zP&gbR4}cpAfn4PTZUM;;=G@;S+1?wugFJxT@euH|gQuOIga4}@AmEnvC%Ym({+M9j zVo-M%iVA!`GEJ-1T5@;H3^V)O0~j7suz;J9gdFkMB)8`tk|fFDp$n3T<2Y?Ln@fEF zAw}jWIBvqt>2x}*t*xPfNLgR6*9jr;*MT`691n(DgqZ(davP zmnO-~_^B!6Lhj^Kh<}!mM6FgE5@&Y?c=UF4wG3R!9vOLdDwio1i$qa0@&m+^F-hDazwk}ll-1Dc;27nEK-O1DzqF;+xvCKUl1yw-F>su5hSe&Q6 zd1nGh{5?V(0CA|b_?hj9v#84YIfF7$vAk&paR3!TtVK+Sn6TEt|EUJBh%@V)?=D{> zW|j#eOFG+*1PTX+xH9%m#R}Fa&bmJUhgbv7BF=$=Z!3&m?IRxZH+3!)BW{d+SOs7W z>IAids-lshF6MLl!6%A=qq`-^%tD29U5rdB#`J6%XB2;>11C5uIO`DW5T_^*gi1m^ za;-^zl!R@WI6>&p2)tE*AjYA!Cq~ey8e}~nq4IkACngdWzJ+|5kLcOkfNyI6aZ+`) z4zbn0i>iT|Q2APRfap0wiqTYrbIaCxC0R;+m_%U#i(9u*!|M51aJ}!|~%ZZ*AV!nrH z6)^H*axx9leCK>fZ|?Hc~wO$JO;+eDygBY-q!vzBAX@ jDN+qv6;u=v4^;RK&~tO2tvSZs00000NkvXXu0mjf1&A?| literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/pencil.png b/base/resources.pk3dir/gfx/icon16/pencil.png new file mode 100644 index 0000000000000000000000000000000000000000..0bfecd50ee9f5bc5828f0c0745aa3e0effcbe250 GIT binary patch literal 450 zcmV;z0X_bSP)Rq1}l<=psl5*5Xz9i;M}s*NP=ugs7Q#8Z;Dyx|}!`#}xw_C3!B-yaPC&0j)XcpuX@rNfq|q}N(wJOjA& z>u+z?dfJEuLePrqzy!)73pvLjxk4d6XNZt?hm_iYES{i}J5y3l?}PPNYDBR7oPc~6 zL^d)Bi4Q2L3pnp!nFxN9c2E+=@XAl&+;2m6a~kZj1r3Mz3C=hmUG<{+vWR@t4q?fJ zhFc(ozZD#Mx`^Q~g1v=K6!QnfuqyD4>U4EjF0eamL}Jx| z%&`kR-H+3GBYr*Qx}frLU4`%n9(`uSomzw)t%%NagXkA*R5Mbv9VLDp1wMo$cOMa~ s3Wm%r7^bwK$2$}-<~D8p`#1iScU4^XCLAA~0ssI207*qoM6N<$g3sK(Qvd(} literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/pencil_add.png b/base/resources.pk3dir/gfx/icon16/pencil_add.png new file mode 100644 index 0000000000000000000000000000000000000000..902bbe61b3e64a9e83333fc17bc8dbb38de2cf9f GIT binary patch literal 589 zcmV-T0?rbKYL%|LWA_fWIdu`2D{$SO5OKC8m-@8*p<)!2cUdv;Kd7c=G>` z$EW|Fn(FlbP?O<0Vr~Eb<;wE^KOP?a|MT$~F#djf@Bfn%{QnZA`N!MC|9?DM@&E3+ zoc~|WF9l}pHx`K1jMaes6V!>;jA6jePPPA^p6$b`dFe#2|9Mj)KBe{f z|Bq~O_~cokR|7X-MzVqeNb|$f8~&eInU0}(LBHGo#?^`cw_KU}|H89f|ND1m{SWWg z{coNv*#kCUa<1I}PY+N0|MmRh|E;wq{}0bJ{D0?2?*H?1y#60=Hu)dh?(%)(aJUfxDNBtTRAiRVBdDb0dZd)pL$P{k)kNc7^C;B3}2}V7~LIt{1J-u zhHUbkuFT{RQI})I5UhL)qs;n91WqH1y}Go3nEOb^5S){rk&d_VLp;L=Zv%O94ll;UWY2R65rz&!x17@cl;CAj}Ns6%i zd5nRJ)r9X?F*V{u^c>>t)oOyZLgJ?ibJq@?o8Vd*UvF46f4UHmRbSVF|2SWIEDX1n z;BVSWf5%?^&f2l_?*pt}-!E-L^YwrR>t@D1jikkgEQo!)?mk$6_1@Tor0i`56;e7( zEUJ>)1XO=cFF0!1!ZB+Jo)hId80xNhvbwq9`W=^}E#<#bon_3QUr(ZC9Yc0=ZqO!N pF#MTD>UVajJI?%>LQ;b@|2K$J-BF0k8QA~;002ovPDHLkV1kb~77qXb literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/pencil_go.png b/base/resources.pk3dir/gfx/icon16/pencil_go.png new file mode 100644 index 0000000000000000000000000000000000000000..937bded9d85c849e8f94c11d9c04744622b6488d GIT binary patch literal 666 zcmV;L0%iS)P)8Wj^3Dc;Nh7)Vsv6dp$FpFhaq;+AFZR+9Q*|``QOHOq0+`PQM-~WA|=Y0tP#QzlU zjh~&FiBopjH?OgXag&EJVb1*cp(`tix4>^L!aJ%8p@0YB85-W3Qn)mtUcTuFPCh_5 zFp9{`7+0aGL3l_R!wU|7A3^w&71O;J5cE-8MFq6+XowfQ5_DkEUxA-KC0?70G2LAY zk3ohto45*oe-^hpQG^2vbN7mJZeUSlOyXme>$P8A?sO}tH35s93jSh^XL?Il?B-N(GohGAU+j4l6$w~;CB*oW5PMx5)+N2;0_Pf`&Hu^ybr-GWl75bc#2=&#=mr%uxI=X7>y z1#@RCc}Q&_##ng6KmSJd$a5(T>mXDS>wjPW1*Kof&ZRxP)A1 zOEJ*J2%-6P-uFsN(314vc)81apZC3Y?}U^RyNqtPD}x|FyWJM~eFHm=EXyz)4*%_2 z`9-hS>nKH+LWpCvJW_K{ee2+Qy$;K=iUCm+-8LExR4SE?bDE}l5@MQWF@R2<=i#hh zg==L9Gagssz>e{B{#CAk4$LM@iPnXHWk?Xw`LOUEW#s_FFc8NvgbK8&R^1S*OrR37 zn*ts~sNlPI6{FG%N)TkF%_zHVFy=yhaAh z=X2P$4d3_SI1Uzzg$DC~VGUH@|Ab+5bP-s zf}lekDhv}*C|@qtVsuz(vn6}P&0T&o-DI`Uo!fjFJ~Q*35i_Ha$mMdDBnkcf{Zg+7 zG#IMN#KgoudQ_hb4-XHS*?AFZ0rmq;B7&;ooFj^&tpU|)^=3~`52;jYz1Vw?_a0Rx z48yGfs!Ar4;mpWhc0@`=1u*u+HJ)~V-+qE9ityeep>g}15Cw(+L(>tztGYcP2m)%g z8WI?B2$&H75*iqdO`xhs2m_;F0wREbncp4|h9RoTvyNF*b=^GgJ()1mIAA2nlS-vH z{P`HIt*z{P@Px^$-ALOK*RoeESzS(kt(5P-y!Yv@)PG_=pSP~AF3RQddS^3Zrucz! z(>$lzPjjfbjW=`88J`{H>zAdW;C~(z3I$Y^g@pyojLC0rIeD}bA9y-jF5#s{_ldIr z*MrR~m>JGF0GxBEDnFAFO|qNb_8S1)y7-tQ2RZ=K!R9lnDvOJY#BofiR3e>Dvz(Nf zD~>Vvx(|TCSA7&p(*S=q07PV^QmNpaBM1VVbHs7Xh2xhQpB^J7;>ApkSR&qkd literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/phone_delete.png b/base/resources.pk3dir/gfx/icon16/phone_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..bbe4f8aba2ce43774553cde9ae33a99626fedfc8 GIT binary patch literal 615 zcmV-t0+{`YP)%*{aNai6YXlS;4Z!H&hL8-fhmgKTOQxX!a)O6V@-K8Cag+^@ULl&X$4v<*AK_y8;GVul}2y`Dd_t?kJrLGh}bvCYd=c z)%mGopJ%7l zz2D3s1QO*{TDvnaF!X=ey&jy3-|>yAN~u&Loldi~v_x-jFXfI-*5AM4z{{J|s^3`$ zDrHA-eA~8yi2SZrt9b8;q6qIji9~`__Bx;5y`}W0jk0Uu*H7W=iUfoFHiKfZ_-Jx+ zacK@S!@h=-yEBPe(i z!9ay7UV6}j5OUI9ni4`5Y%nw>Hf=V$o85J0L$(BM9C$nL?Y#NEnRzq9bzKaTY&Pq* zS}kNU8SyW>g#U=+I4Befo7!dmYngKC#= z-5ZhYsr7cJNXPwt4fq1HiGYhcM+6>@yO| zXD@>K)$29`oe)=`;M0Ve`z_rRHM)ytw;{NqJ92_6VOk@C*y0Ex)o5ihL^ph1#5YinO zyxORvZUfgg!GxzCWTNIM`)KJS{p1Ntor?_ABp3_=gaD2H85Y)0(rUlQOh{nzR6z<5 zEO0De$IN)yJIjF82x73(uJW{bfy*E6{#GD4S;+brQ?z@ND2z~($5eI$1QYf0H)an^QOO;qRuu9YpYp4SM;xg>M8uf2%- z4&`D7e%l1>UYk(D)RldpJ=nl|j&F_OWY^F0mWv<>mGbk{ZJaBpo;hQ@c$JuAE_G z>kA@^Du`N&ASK|$QI{P-M0lOJM3Q-5L||^Kgud8yZZAIFCr~v!RYRTlfoYQIjVYQ- z@`-LI*iLI^b+d+Cy~4MZvuq`bP?tuvn%~Ob0#1}j{!glo6%)=lNp(n3tLAI=Jjyf5 zcAt}odBk@Td^~l6M0_0&@I(!DhKN#_UXGgLY!5ZXP>M6kh|a8&xfSGGV;!Y=6}+16 zW8(80yiCP&qNo@dN3uwC4q)Po`JMYauvk&f<(3vCC`5{z7@6s%zN&%Vg?>B{1q%?$ z%_k=(4^_X?%By$TULFLLp%=p(3S@Dy@)`hl&UZ8LsS648`vi-#v-`XK+j+9R)hAFR z7II8S$C-?d(caWU$51O7Y3ZaH1P*eI^=;vYrRAY}4b_cQ6xFiu{R87uV=OPNcLol6 p&h>5K4&Ww`4Qv8k6OW_qzX0uFt{M8}XYT+2002ovPDHLkV1m?qHvs?u literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/photo_delete.png b/base/resources.pk3dir/gfx/icon16/photo_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..18b67df43aaa0eac5878317173146b3d9b1dcbd0 GIT binary patch literal 703 zcmV;w0zmzVP)E*UdrD2cU6 zL=;sJwLC#yz=`8-_cEB(*e?>1AKiu zNOgJ<--)7PM2btu+Dp1gE<;I?x-VD5n8Id~ED*w*PD%={_G2sL||uq&`2V z_~}Km={ZusY9dUgAdI(_Hoohq@7)$HzP78<`F?1c)kVkm`LN_N*5hrp&hI-Kx|2(@ loni4BC2TVW_f8GCzTapmv2Abd86N-u002ovPDHLkV1l>_I==t_ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/photo_link.png b/base/resources.pk3dir/gfx/icon16/photo_link.png new file mode 100644 index 0000000000000000000000000000000000000000..e6bb35fbf8a31d1535fd86db6c0c6ddd1cc5fcef GIT binary patch literal 784 zcmV+r1MmEaP)s|6h%ThKxv*&vL}(yVunR&6mG%%uQ9hSF)I%Xelo0h)4-xd( zLqGN=k%rVmRQRAItqZ!v=x%F^nmVoH&V19IZ?+#Ff}j}=m$`HAIp^N_#${O+{^ycL zukHIQ17jA4Nia+XlVC@~u%nZc?84gCW-!wP$PIU739wl$o}wIMVAN#S*o0t|hk(g< zlMVqh4Xn&(kzZc@C*`t=a`=_NZwD47?dBH;-+~(eocI&;d__5j(jE0SJsu3+LygbJ zi3P4$+``!RyM#N?T{EN(7)2Clls8K)VEHK;XOk;i#T^KaXUF!Q$`my}!b`0m1-3#3 z)NBw5VM;%Qk;VO3U7zL3v=%<1K++*0%&gbq*~(d*pS%Cd zf!!nVg;5n>7%O0UbqZazGSb=xG_eayYpw9IBTyIHu)YzXS`oW>58Fy$v$n`NL`nk? zKh~o<<%Pfc7*g38SZ$Bd5Pk?eZ^BOBE@YbekoZP>vRsf%PGIr5WHE#fqgm9`-E*P` znx>&)z5%b_kAaowINIHZ63LBBrU?@h)licuNVYPgdA55>F@1RiqOTJNPIltzg;V&v z>_Sjc5RFEWNoR2D=52}#2vrF<-hUD5r&$QLGRR7WSH_yli}DID|1g)X51>%Uqqnyg z?d|P|$K!~_V$ky%;vt>alvjEk2Xl!8KVh3|Kzc#tF9!#1@RK(*Gz5>w!*ljX_S{br z45wp2hH71Z{*94Hq`9%N@o7g#N1(2*j!BYKmCa_6OeW!WyAcY7;P?B9*jQ3kRTv*1 z|FVT391e@YU@%IG!-}HRP?Jb$A(zXYp|~K+@-W41x~`k)bowhf>iz+8udW=YJH@sD O0000uGbh)OD` zgcc!@P()C+7(|Syv{2NWl1}%|Ip23$OfzL^1Rl7H!-a?UPH0>AuIgq>Y&*abtHh}bOQd8rj^1=cFY2s6_~{FH~Pqa?m7MUmIL zXOcRvh_#B#q^Swkk*#g!jm7WXi&VJ<8 zrFU3SGIfR^Sgcm?D>^DRQrV;2ce{u!WPvAN_Ooa<6KaGN;mE)!NfIOa2cTl3sg$9s zVVo(vQNs))-_MaGw`pzK zMsTql`^! literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/picture.png b/base/resources.pk3dir/gfx/icon16/picture.png new file mode 100644 index 0000000000000000000000000000000000000000..4a158fef7e0da8fd19525f574f2c4966443866cf GIT binary patch literal 606 zcmV-k0-^nhP)Q2rnAt>LM%-F zK|rtwgcU)}7x~z1Hrcs5bH*ZO$!>xO8K#?==bZPQ_ecnV>#P`H`QzGaRhd62G_&rC zTLU$c7_x*nFP_dW#Q+*);mMHE?j)HexK784D4x9l_tfpz2$@1y}9rkF+ zI+J5NMWeZyObc!d+rUc=>D+uOdAOg#%+Ej6h+wn5^xPmVVH*Eu446Y0A_@ zo$rlds-+sL10DbwHdg4=I}KDOKH)5`dDSD>$*Y+lYhxmAcGuF-%MWsHUJr4IgaCsM{ig0 zSSBT=s4DwP*iI5?#me_ElhaWObR8DO+&EW-R6_iOTG;>$!^9AfH5RBU`HBdsS8XyAx|wUq)E7h=Ss)mVnuwi!$R3b1!m9&Tc8e2Ah* z93dsPSIWMcb|P*JsnqXhvE^WDxdW*bQYjAj-)O1aj{;`q7kRbTjhQIKR1t1J@W^=H z&KKSDw_e_z=&`ic2;k(#VF6&)C&;9iap&Jt(%M18^cYK-DUQ?~rD9htLzB%~biuWVi^wq=sbuS+r^MZt^XM4mKhUNn@-HDRMN|w*p+XTw5ejxoBfqGYGMX z(mxA;rQ{;Eh;XXz5&+jv+-LAZKk(eOLY8>^WN4-(D|NlrfBplBR3bVVA7LUsOjp|g zy{|9gnht;`^xt0nqUO%>o{FmI&DMtF)b45G)516-?}wS2P4@j4U=z{{Tmg0fDWHG! bUcBoE0(26M^-PUO00000NkvXXu0mjfKPpmF literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/picture_delete.png b/base/resources.pk3dir/gfx/icon16/picture_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..cca9f535d9a699716b2c735d0d72374472b9e1ea GIT binary patch literal 744 zcmVP)hQkw$4DenXv_1k19q1k|i7>6Y(!p>Gs}5>iPV z&!aPy~rgIO_{C4dkZ zsR>k_stj1H2h_AgX+YF5TH#m%V^&Vp0x+fl@M)z~j$m*Jv?7oSAwrZ(QKF$u*tP{m zthQiG!$Q<-Z$2x93SWCz>;N z@|O=~WGn`>v{S8}AU&TvrXK^HBjlLS_A2{fi z9kE7URXC0c#|c`x8VSriV9%*u{Le%1vY)0{oXs5_c45r)I=(B4=z47DhP@!fFO>QH z0C=0v;craC(Thvo`;ypNY<5D9c=%{=VqZ;}9mcGE1D(-CbLGP`EAr$5!D5yQP@1<< zHq*lVt!kNGcenM0nj_az3F$c2B&EFMYtB~ns=5AO0D$4{_RHnM^m$u}4rQAu1Gf)n a7BV67Uig7b0z_wp2kkRjeX{OGU(8H$_BnrJxI2 zYgf8Z1aYIHLaSgAOBf`OQi|_q z1L^n?A4@G9O#>X0iwC~zJ`7+;C3bJy(9+;Iju1lU|Kv%CqmXNNU;Y5h0cL$^+qNTq zyZ;7{DN16HOnRJzStL@D{B(k6FI}qC3Jg*l-I*blLd-*rAOcO((F6qA7@7KUY-@y~ zUm}Vl4BMu?WeM5gYHF=|q+ICA0FZ#D34AqyWxkIeO+9pNK>MVS5NOzoBR(E$7F1q?VDFq+r9-q zcNwcnFw!?b=mk?=WoG?52ZK`wiKQf#k}v!TdRp2LW|5}OF5IPG7i_ZcJ}<$N=fj|Qmw<{WlS3PTs~E*h30u3Wu0+!MsALn%mSe|2{r`kBGYM;ZG4 zA$DsgUOp#BS`W{b9~5FkFJNk1ng@Oy8aBjAUQTxD9n1zdX_3 z|EYp~1lYByuF~C}HrA}jpiKW^Wqe}awv&Gif3Bf#0dDv^qSF@P-T(jq07*qoM6N<$ Ef^;Qtp#T5? literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/picture_empty.png b/base/resources.pk3dir/gfx/icon16/picture_empty.png new file mode 100644 index 0000000000000000000000000000000000000000..abd2b9bb48252338e831bb54f2fd76037b1bdeef GIT binary patch literal 463 zcmV;=0WkiFP)h0wrhpX|Hs7;Pt55ta+?_WPZ?E%ty zcl7GX<6#&ib$G%g0Kx`)KASRL^ZnUGrx zCTlifW8bF0Zh;X~MQ7g4Lm|_~ykU(Cppw z+zc^}2l`HK1P^+B{r2nc%R}+A|9PB!2fN@?ZS6gu^9@CduRn)+FfsrD002ovPDHLk FV1m%L!2$pP literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/picture_error.png b/base/resources.pk3dir/gfx/icon16/picture_error.png new file mode 100644 index 0000000000000000000000000000000000000000..d41d90d64fd3d6b4416c2b85c589d032bdc71c9e GIT binary patch literal 755 zcmVVGzfE-|p@0ZqAsP=fxPqDMk&P@d+L_YNLgS5CkC>7CvglMzFFJY-|-o!A5+b z=|ybBs38g>N;Dc&G%;Qt=I(ay+Zl`CBSswQ z#|XVCtO{SJL!J-UQKM@~(a6dDITA7E2Q(F1a2yxMK7N0B1$U6)?#%Q-}jk~LK;H{Mdu0g3t$Xtg(#^~ zu@U8JL@bs>08>RJA>|lU=d0=fsLlZbnwgo+pm;=*5ZMG{(zH}uj;$IcG}-TwUrmvQuWfY-v(a0A7mBKGMB480{k`Gwrd zoh)wKz%qS+oqoMgL{)e>ag;=aM1-zroI*z@>Vi`fQ`=NeGJS_->-rcUzJ_7%FMz6I zfZcP(0>I5rQkwlj=KWo=`2$cHWZ>#;wjMdfyU_f0 zDIw7asE~YnL~i>D+Nb-2f%Ao004MOw6jG(9bt^sD0_(B`@-3UG8+}Oq^7TmR87gHq z^{z(Zj|9OhI=go`Hj0k}n2Wat&x)EtoM`^XiQA(4=`EcSX1hX?Zv&{tJh}0LO}%R| zZXJZXczp5nn2PK$e;NZ|;C$hIzVB+g>%2v6@sAZ9+;BCYpAYe>|IGE&-@eX9aWHtH lx2&S5$Zx4XDmBR~*Li@40hl?wvRqnZ(Ao1QJ1rZCaJSDB{Laap9suT~%lorMMMz>qEQ4lo5g<`B}Oj2V=n8e9sGWVQ&&hO_UijFU(&+eSXhr@Fo^Xu=UKZ=+y zSDmER^Ln)XSd1Yp^2;}$?>z+&i<%Qh5A<$I)6^JK;J=ay1fO&1%7d?gHDJ|Bk|e1) ze|3qB8Vxf}f6qMSVjZu-;&Pcg4?5}4L1MZ%eY~F_#ym%3=OKy;L-P9AJKpf3Z(ci39q!_wFi{`Mq{ zJ*0SVfxfPfu_0%B_aJ93?kA`cBW^;RWZPkwP68J7<$6(vG4fo-LD8L1PKVrY<-5I?FU$KEpAQ! zS%3drRE^CW_8Q6?$-E<|Fjf1TTs&TK@{qG^8|>~q$V$E%-IyGy#c9#hk-YPRo_%1< zGfK&Ph7X>e4SjeC1Qj0Fr>RypGdgpPYZD_2&U4uO{M+dFqGrDfI`r}vU#Wf3nK_3O zN9G+nx_7Z};4n9*uQM`neYIg%KAIiYyXMtlye;pYi<%$y9qPDx|Bpvb_;hwy#{vE~ oFmTp1gA_Vi5(egnb@KWBQ*sVbcJX$M%m4rY07*qoM6N<$f(SNMBme*a literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/picture_key.png b/base/resources.pk3dir/gfx/icon16/picture_key.png new file mode 100644 index 0000000000000000000000000000000000000000..667086c0dac0f81c56a83ec870f5bc6b1c730c58 GIT binary patch literal 794 zcmV+#1LgdQP)i(Bs^(FFyPpKpHC!eKyq78HS+{!sY)gF`!k>wO=0{1y%vg)C55giVMHh zNLZjDD)e>F5_xr$H7qVij6Z6l#lDZEo#S8jp^Xs#LS?4Faa;Ez>{UJmqCY1?^_`0-6PZ0r?kYkldRPFs14}gH z1;XjS=qQg+n7Tt=o5FGD5l)Q1aUPN;FQ-#iigoT)M@4j0#P}ZXJiLe(S&W*&F-zdI zV)Kj#S1QSPWqCw~o~UE;wq4zOL5P1)mZW-%Wa<~X_6%XOpAovjgWD-GO~`X?C#uVb z4qu)emA(`|jgD3KW!etBzT*Ajdf~mHPuy(&G*Y%PK97pH7o`P}~TW4UqW>+Ofv)5*7e-t)=%JInR4ZOz4aWnyCP#5ZRjUR_W3 YH!v??(E);vF8}}l07*qoM6N<$f|C4jrT_o{ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/picture_link.png b/base/resources.pk3dir/gfx/icon16/picture_link.png new file mode 100644 index 0000000000000000000000000000000000000000..42dca7440be7b2b2776faab865b7347a8bd14b6e GIT binary patch literal 835 zcmV-J1HAl+P)P(65Slt@yYeSUmI*|#LP@Auh-f!mltQ}@UFj-f zTy`ZC-MO$`2%;Ms5JAvd7tz>ITbyM6k~DRa-s#*s-;awR%^2|P-p#`~=RM-HuYOrF zM!eCEjUOov%l4kG1mES_+pnFz1R#wS3$rhm^1km2ArkzbItH}ra{arzZvy*(c4R!y z^Tp@O59#oLJ#mNO!X_!Vg|dd7-4wsw&C+L2AQ|NH*(}W^J9t9zXs3^6BOu6*ARTe&GtwRexKC3|onqtm zO$IVGgx0v7JjX{D$oK);nE%e=iGw>2&ZCW?8*7fVB+`9_T;Ulu?ypkY`~V{(2DeV} z&F)Edo7+!axbW$fm6esN(prlErcYl&E6w*`|3Lro0p{lB2*Z$#(NTW*Cfe@1shkl9%GZURQtpgZ5UN*>kV+$<-x(zr9LuG@x8AQ?J)q`gn;(qrtI} zlWO7YtgKWj=N;b_Elii^3NP?zJ)*xq3&7=z@6nAF^YimePEIm2GsE=sG;tjB>`P}t zfNVDF$)prte0lTUi?O!lKQ~n}(XRV|c=!Del~PJBE-sQzrvV7V5UmYAeS59-{96mz zYPH%C2Zu2+F>zvSZ0!2f)YQ>Zsbr*-N1DwhYinzGp2yJ85QRbkrPR*)`nt2cyxiyk zjE|2ef*>fT)9D+Rv3n7{sE}ALP-~3!5;ts N002ovPDHLkV1iNgjz|Ci literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/picture_save.png b/base/resources.pk3dir/gfx/icon16/picture_save.png new file mode 100644 index 0000000000000000000000000000000000000000..777fb5d2e6a8418c573972246582c21d2c4984e4 GIT binary patch literal 755 zcmVe)^Pp+~01yB`w`9=u(Ho~0 z&q0|Zy>{}2gZl=9K}x9u0000cnYNkw{OYaOaSqCHmHYkvAYHn)ZsML%y6Mn?Rm1M4 zCbIimL%-gdGZROY_IT&jL)x4YKv_2wMMsgSixr3VuIl&xwpoodZKLe>9X|MwKbLly z@9mW{08m0kQ6yEY>2=p_>};yqiMnYtv8~_l+pdQ83=1I;07}RxQW8y8wNsO(vNNsJ zxzT2%smQIeNFo9Nln_CYl7W3j+smTUwfx(8yZemmMmgIvlXtBAH}d|cf5_39J9FWB zT>bgZGbKb&6v=F7!JU=6<_61l#uG1|c+xA2v%dWPU+)_++yuBPsf8gS*uy8tE)TNP^?wUn|FBDi_)Ep5))oIO#kS?(pBVA^IE&o0V2 z1UkY@NmW(0wrgcXNO*bi9DvTz4L^KUm{e2mUH(gvXxc2dSs)?^X1ZCKKmdStIIqc} zY8#!Ri;%QZN+O4dtZAm|x={|gX;Yrg9Xs$WDG3lp>Fmkfnp~qGh?EV=o(rGc zc5iE2*(=lK&%R!Iu5ROK1ORQ0xsI-E$A>rGws+=HNnvgLk2jzGKw)59)ygxcj-Lkr zfNySo7mq#2f!UFlj-4>yTcBWLvS9zN#!QbgB`G2R0KijcuYCLXBg5zC`|}3n1DZUQ la+ac%)7bB~m#l70{SP&gLHlD?H{SpN002ovPDHLkV1hOfWCQ>J literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/pictures.png b/base/resources.pk3dir/gfx/icon16/pictures.png new file mode 100644 index 0000000000000000000000000000000000000000..d9591c13f67cac8e13632e1c841f7debd1417a5e GIT binary patch literal 704 zcmV;x0zdtUP)W^i!ifsTc(=K1_V3&M#zHR|lg@#Gff=58Uzib9<$t0J;KqX&BUR5k)rz$& zB8cFtCF~4|SkfeZK0aC--xN^wy;E1t?BD8nzWmkmJ4KipCa34l0-FPtBg&rV%afN2 zgWsE9wzM;K6tG3NTXA}ea>>OQv13!S3uzM9$46_o*8xQ6&4HCL+j_Bfpv&{BC`w^1 zF1}kXxg=@s7HD;HdhR^19-zvqDt;>}q`SxG>C8uWsk!U~u^=L-t>B2@I?m3_$iUdt zY>+1Lqw&$&NLPoX3PquAW?h1I?p!{72+!;L*RlW-rlx;#dhQbN8zA&r3m}CfJ#G*x zp4Z31*EX*k*Xge=5oLx?i`zNA>kdcv??%LxH4CUBC|U7?JP#?Xk^{N5`2He2rEOSJ zY`MX=R)kfHh*sAC4)&WC*-o##!|g6raU2I#Scx)PNkXBkgeIjKCA3IE1y$N>fGA2{ zOw{KO8Y@F-YA9^{3y@eEU-x1w?+8sq(AvYkfy%}^xOc5~AK>QHtKmwQ-3^sNYaxgW zh6lzt+!*2ghff42?~W2UMkn=!+`e+&#r4!m&t*Pi{kVy<{yV5rBn%1W8t zSc#vBL6V!9;o`ktd-^>D7(tpD{uAK>89pW@UKU2M&7k1<{}&?u{~w6_M>q^XHopD# zj{zRGFdFC`m|=JgcyRw`*p4$_S3h|7hvD1L|3FO;TfwpQ_dj7T-0PBk52V5r3LXh+ zs&njyMf3kZ3=9ldq8w*5KA0f){@b^|?-~BUyz(C!4g_3)48VSdx!^BW2jDjVJ@95jSE5A%ge_ins}gi!8E`O6kJ1h=>~tC15ut zhN?)5E3L|iZFJF=*g_=_^DuEHTaU-1<9YtxodHgl>v@>xAxV-FEX%^_baD=dL!A@w?eOp=8xA9r z$snChBauiTl}aHRje-D@{otVRRsdtSzw(Ddia41}D%C|%#M#-I0`hph__Dum`X_*4 z7_*xaWU-tqSCqx%U9ljCczzCMZ!dBK;IUe#x$SLaNDz<55s5?;ahR-}o}MBQ2*68l z`F>+(2iE}Msj2D2$_lc(ySSL0MT}t}2m&~cLx}9q6mWcetN>{;SX*CrT>(6Ug9d4F z5m};M%*-G$F@fJ>V-S{>KqG|D=L3xpCnS{LVPkU>?`*b81z@kLQhCS6k)_L&*^D@y zW22*p_V+{V=|O024sN$wXh+oA&=3Ry#HoX*MuT4s4fs@Dt;@Mg^Ccw@tmWk&jv5;!R-?J}*4AEruB^=3 z)as{q-o_UN1^M%Zh1xg8#irLqMY?&F>VB?m{R_n_>>p`!{|5j7002ovPDHLkV1lz) BL~;NC literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/pill_add.png b/base/resources.pk3dir/gfx/icon16/pill_add.png new file mode 100644 index 0000000000000000000000000000000000000000..ac9c2df6a48474857daa68528728f6071bd49373 GIT binary patch literal 797 zcmV+&1LFLNP)wFU>XvLNg!qz8X`KdHL8Ic>|z&@MT9el%^8`LU|occ zQlgXyos)^Rc@rpRGB@Yu=Fa9hZpXGU$AAQ%iH91g?p_k#dfDp*h|kV24A$4zd63m+!+VoS@kfBc zU{G2}04L^xxs05c^v<`y8MCng!}PT8H-L3uppDY&5ha2^AON4w$BR9rm9@1sI2;bx z2%PheO-|w$fTy*!EjToU*whrZIyw!Dp!y^xz=K3bC@X02SsM6E}IlSWeC{yIhXw@Gt^0 z88#am;j66$Q&|abSsAF}VraXr;m+_SyjkeQ9Hm3|L=)<|kK<(XA+_LnX6BJak}cBL z2UaYGuciicMFqU2rJ#z6Kofwp{R~Dv-p9z|18#6o>#v|&FXI4Pf}YgWxYv1k^Nd{n zC8SV*E-#0tqy%n}2s8n(g@riRD#Y7`e(Zim=X*K8w+-~9r5!YhL{3I5j)ocM|S@AF_salheuz%+t304scaAki# bRh<7TqW0OL4=7q900000NkvXXu0mjf`H^eH literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/pill_delete.png b/base/resources.pk3dir/gfx/icon16/pill_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..c61592e8d841d675a9848ab253c125f874e5eba9 GIT binary patch literal 805 zcmV+=1KRwFP)|3VJFEMEiM8|CV`op1c*cqh-v z-FmRM7mTGPK$#3!q+J#%oJot<(E(ad4;1HLLjK((XsHAs2fxdp(&LM>=n*e-T*FCG z1Wby9QmL|#La61YrwMc!FrS9DYd66WIt|*#S?SaJ$XKLHP}pCZR?@OruyQ#tNp9t( zC}0swpX!hG8ECq21)PZ}FfaO`^2;k|Y>+t2;6Z+;Q1}*KU*D+n`_EMP{fxS?QNDq| zvLMh7;1W1}A%M%b|IEOMA2^F?w4d_R+S=poO-&z~TUvY-7z=7T4Nf9PdwY;21x)*5 zyXX6ENL9%*|kK`a4V$F#WqLMuJ$OgSWd=Bt jX)rmwMO4o&&7$$&XRoX@!lr5t00000NkvXXu0mjfznpB^ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/pill_go.png b/base/resources.pk3dir/gfx/icon16/pill_go.png new file mode 100644 index 0000000000000000000000000000000000000000..e5c07d415dbe960ce2f2b1a031a4f437ca5c7b04 GIT binary patch literal 817 zcmV-11J3-3P);VJK6Bvc5}LQ4dy(CN%{=H9v9nFNf%=)y@(CUfukzjM!j<_e54{Lf?iSHeal zQfU!{>y*-RLddJ^?Ch65pN}5y3x7MoN;rJq8Lu+X~|k26(OnW89+3mFHnL?XfF=jXqVO-y7Md6qv_4vmlZdA;7d1zs;W0K6hN z#HbFt-Ht4`JBN#J8@a~-p-`wN;P-b1d_JVpX%oPE2lv2y9~>MY$K!!UNar!Y>fm5^ z6{Yu1yWM6*LwqPSLen&JotuiZrse$x*zW4;_B$M11vVRKe?RouSyOC?4DpkZcJ#i# zhRhRABt;RaR4RM~SZ!~=nNeEWmBD)^lanBk2!w$FU})%9Wul@u{|q`_G~v_o5>ler zWR7tx7nkeeDyype znT*+`%}v~Di$dXJRCy~hQCWHZS>b%yRm?=jF&uugtrA>`^|8-Kcj0MPR_;lc>-o7r zpwS};ZiO2elO#PVNv&xJ(_(3)jIF7< v{eEcNHZMNv|IbJ-M`( zKwWL~opzjJe^WpCmV9E;(0&ut2;4va_(#>M8)>9$R5viQnf(Nkh~VM$y>J(jqb$cj z+nL1Nm|mV)Gm|9MnHf*7Ja4OEAQz__^LRKOLEwqpiGV^^A*T=#&inGm-62Xs;dnSp zKj&H9T*boh2i)W+(n27l!C)>fq|L%VB1i ziC4p;NwV_}ZjW7$LRW#(_bKF#hp=!IqNO26Z*w2+LEwx{PVnZ&Sn}T;mtzb$;qA*nT@@+ zV5uQ@iXDTPoTbV#FRr~z04|PPh`wXTNoCm9*tG&?e3+fYl>K6+&3|Cc$KOpL`ER+_ dcRl5U#9zn6ZO}GF!C{kgV#7nZ!}+IFwq-SXfjo|dBU;$2A*R+N`fo=|&GUYL?n@~UJ} zRwmI}jPAB8^01Y3C+^Ijd+pCXe>~g?4Jqg4)T#41=X}pOfxGiRR{6W&>CB0&nI=@t zRrSu<^!c5C0)&<(_cUQ7TI*VgHN*l@P5-TfC4f_@-VY11P%L?g;zAJ-8T%U`aCgp( zo^&%s)zGr{_QtkAOc?cV zQv@Ya7h%t}T`nSsD7Oy`1i{aDaBT3P$D8A1r!%M-=8CwXt~6AISyR6jGsiIoM;>tZ z&|vV(9f&CEifGyEVzQcIGxNN8`GVQmBE|UvZp9xX9KCnIMU)jaD^N2^UMg#1ikMNI zccRNH*tm5QYno!*e}0qU>_gJsE$2etD<@XAvnsrb$ z6AdYytGA&+iFC(ifFqRvB@qNA^X?fNqMb~-l0^}rXPZ}>v4 Z=Nr{rY9&UI$M^sM002ovPDHLkV1hoZLv;WE literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/plugin_delete.png b/base/resources.pk3dir/gfx/icon16/plugin_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..d9c3376d4593e666a148192e2527219c09402b0b GIT binary patch literal 692 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 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/printer.png b/base/resources.pk3dir/gfx/icon16/printer.png new file mode 100644 index 0000000000000000000000000000000000000000..a350d1871536eb28fe2949936de1c79c1c26269d GIT binary patch literal 731 zcmV<10wn#3P)^msfbTI z9jQ^EwMRD5xNEm*sJPjH^k)@gXT@kl5ii6#6jNXX`Yb0kVgq(zut?ZfbRr+DS= z>q{33dTpWN$tl6c7nxE)4Qur1GCxuUnp5Y z5HK(>u&W4&EXz<>UtfnPivJ`O3Zb4K8yl-}7K;Uh5XR!-B2uXo6E#Dr&Ck!D<$0b5 zXEK?PNF*3;w;Rc15`MqGDN4rSaGd2kJ3GNmOiaM%^D*ppJL2&;mX?;95{t!PwOY^e z?d|R0=pOKTy$qMj1$rk8qtS@b(NQ*LUtb@(y1JlNtJzsS-`3U!Ze(Pn>hXBkfzr6} z{3Vv(2AlG1;RQN6I#_mYZVs)jt>6p>!_3go(6&ye1Mdo>SRyz&A^1T#%t=UROW6Bf zz^9CeqErU&3`3<-Da~6HQ^UW&yCT)$Cu literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/printer_add.png b/base/resources.pk3dir/gfx/icon16/printer_add.png new file mode 100644 index 0000000000000000000000000000000000000000..d228d0580d8af0dea62d44c8fb33851568591286 GIT binary patch literal 782 zcmV+p1M&QcP)z?``cAjK`}OU-rz95{9r*BaIM4Gr-{-(903g`rl=7|Q zY>&q#(t7d)h;*K$NIRJnY9{ifSDk%3Yqu%bRNiu?SJ@=KZ>A87|74X-AsAty99n|( z-hARj^YETs1wxH0v9ZNr=5v;if#(y4@r4vpnH**!S=<;|!byew*{*^rjVs9uW{F_- zOBPd$X*fS}2(N5{PqwnQg)-H6=C1;^T3uA7nc&tpIrzzK{^i`S6lvJzwqOp#u}(%i z-QnOQ5=l{kfHX@9aq?JLBZA;^9v_InM?~Jm3>{-^K0(gXsOWT}uC6XF7K^1+KpM*i z1_t2udU3ADjTjMxqIm=f{;xT_C!@GY3I`b_Mg(VWy5Vp*AeYNgUS3|t3w&fD8jV7! zRQ?xyt<&j5b#?UuFW|D-EO@4;r@^x9KXJKS*sgDFZOsc*Dit`6qnJ!4gu`Jf`jaQG z`ylT>kBfIiU~X69sr4ZkhJm2Hy&b_|kYX?x5DJB0x7!PNVC;t4#9%m}$GeCXy*3$Y zdXJ#A<}d_pZEdjGY!sbNhd>|zi^WoaL{ou5|6L5u-3Pz4qmAety@ZmceGrg2U^bg6 zdc7XxO(+V50xc~qG^X%cF-8K9v2zXi^eAcG3xP}~%NdPED&QMmynKbRHxmUMzj6RQ z)(hyeN@#PJMM4uCZ6X4xRQjmCzTQ_`TMI_-Mk2{!b%VnK>(>B<`N@M8)qp=c#EPlOx(m^7ZttmyEx}O|KIyO@5`Y8P&=Gak4UOI z9A;ssgC#(yb0mbF7m2Kp5(`OOSQV z#ZO&(x9_ilO06xv9b+)LoFSy)_{?B*K8a*Hi^)I+ci%6eOlj%)tDr(_OK^fIBAEJ; z!Ng(;^a2C_Y7|^&tD7+hG^6Q13R+uR3oEo^%vO}a4B2gFCHu3B6wI?R7(Eeekn#D93#ZJ1gl2JlLaG}i(tJMm*T#oYcaselBlZ9X~2(?=M zUvRZFO{2QHdY%(7nM?*8PNx&$aQL6tY&PuFH#Ie}lt!Zg!!SI3eSPrz{k-UR9C{V# z%f~QSR)Asg5qx^y2B}mEN~Kc4>-F*&3 zz9|c^P`3wzRrze&$pas9{spPtk*$9`fqKI)>UhS{rM!uL;bHz3OoF`S0YRRM%X|m5 W5Be1eiT(`$000001{r$78XkvMLD8LgLPI}p^3#ZkL-WmU{TI1 wPFcbdW00`FlWkSj%Pe9r%we8QTmJp#H==T7N?a3H(*OVf07*qoM6N<$g8eR!YybcN literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/printer_error.png b/base/resources.pk3dir/gfx/icon16/printer_error.png new file mode 100644 index 0000000000000000000000000000000000000000..279ebb0e53aa400ce0d56ef55306f5dfb96d18a0 GIT binary patch literal 854 zcmV-c1F8IpP)}sFDxRh;iJ`Kl6P99uC8=RvRI)}HkrHImRbEuyMi<_M7fBaobX62} zlPf9eDk#N5YwAseOmSEsTF>{Vk~BJwPOZ97&_0w~^#(52_;@cTLqJi(-d-dO zvy0z<;;>|=arHNxEKc`4{&eb zea1EMtc>>BMVM;ZG48&F`h*Eq>ovGsE(8LBhpK?hZntZPolYlgHd}_kX5cNYLp5^E zb*L&CL8-M3MMXs#hKGkMI7yNO3hl7p@7Fd$q0m-=#1ITC?@)2H6H??2O!iKMCSF5K zp9Di#tgo*#L=;6VEG%eHiL^k7MxzuPw1YmPxausBn8w$q&yk%MM^@5@dC$l$hfAl^ zSX^AxJjP-%sDi0f3c9o(1x6k@`7!F<2eqP7^c%`s`Y`+95u%n{1cSjX0hOQ*y{O+Zbdy2gRyjvQ3h zv>+=d1Vs$f{$w%r%1ckkkP}{*4p=~bjiEG00qbx$%4TP0g_)U|lFjNa+_=z$wTS^( zny!P;mSp(-Ao?nl)g99;BUFMjTA|CfAU{0%J>xZA8Jd(h+FBPk`oK!`CCkb-<{9 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/rainbow.png b/base/resources.pk3dir/gfx/icon16/rainbow.png new file mode 100644 index 0000000000000000000000000000000000000000..5ede989a4b9aabb6b4473a45870acac30ca8b327 GIT binary patch literal 655 zcmV;A0&x9_P)u8hXXmW8$M^Z}tgueu#dCAu^FHtQeV(HM&<>-oby}}zNt6*; zqOz!R7;sXQCXnvAh%NsOY!BYTPS6Ya_FvE=N~N0XvE{pt>_abd<38j9C$Sf5#*g^{ z6#d#i;i$++U%QNK=q`5eyJ3V~u*Q$0G+EWp#2~B(nj<_bDs2zkL~hK7Lhu+$HfYV9 zg88}w#kZGWr6!PHZ*X)j?F`*Ue##H?v8xKkTTpy+9>!)Dj4xM}tnU%z-?{#Jvq5LV z)@YN0%~$O(K6n)LZPSD2E1d`=S}^f`2uGvZfdMJLnQPaaO}!IFvKxB>&n|bMcm4$0 zUpC_Oiw1-@0yr|I9f+!ueRKzf;l|(20%tyTVPvrtXKnCG%!j^695MYP&h*dy8jxmG zh3GwXFus{<)0uFafajiFK;M%%ru8Id^v`&@kgN`{8&+n{jEe5+VD{Q{CLD|<6d0af zLr+L2Y>HMnV2KT5NtiRE;&b?xw@c1+=e2n-zL{&& zned;z;Q))>W;sY6uKp4No)iE8002ovPDHLkV1im2E0q8M literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/report.png b/base/resources.pk3dir/gfx/icon16/report.png new file mode 100644 index 0000000000000000000000000000000000000000..779ad58efc5776825ef81064a042eceba274a928 GIT binary patch literal 649 zcmV;40(Sk0P)sm$HQ(N)Ek< zrc#vXMLdW}TWpphCZsGREkUZr{Mg;M&b;luZ0IGA9rnH1`DVU1->eh_0hG(-dw<@) z-1S-xc+D!@wd^?Z=a`M%%phe@J_EnT0QpH7V3 jcG~XA#&PRl)Zh6(yXt(^KFGF}00000NkvXXu0mjfDwr>g literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/report_add.png b/base/resources.pk3dir/gfx/icon16/report_add.png new file mode 100644 index 0000000000000000000000000000000000000000..d5eac9bccdbd7b67529851a7e325f8da95c4b930 GIT binary patch literal 714 zcmV;*0yX`KP)?M^6&hEY^hlvJDB989RxW$OpU>|&7C!ZMnz(wW_8 z%4_O$i8?inSS;2{tXQNsU5p{a{r<(%`+a5ad~p{ZcsQJk=lOolb2t(J5|77oe7-}2 z8KVMDRRtsxN%c0hhs>33w>$E6c@f{1U6{ODj!Y)AE%6~nqj3krFv=;j4xf8;n7mSs zcswprG#W)D5)rh%zK(P{y%8WLn1iEUz9k?Rl2bSwMk=Ki?=?40^$1L&Ozp!v;TK7go1 z1mo?ESa_ku*f|-WPTD-Rl{2>3{J8$g&vy`u#j*tnM$gFjf+!$&6%tLPyOTK-3Sn(+ zEy4vH%o9A&V*a@Xqo?-@=GM0>Xny?%*LwVDvi^qtyY0yjr6tSA*qBm!!@ft$$ucnaoc7ie`(Yhjtzp+;Yl%oE&J zW7eX=@UeUVO{d~c+^xa{Ys2O>>g`5NQwg>Z3>}pso6Yhskt3+RQHl;{1I$h(Z#GXU z#RLX}K{`;k45P)CROWRt-dv0|g`BB9e*V>|nBUvKAsWJiZyICw7K_xGH4{3!sG!{InF^GJm$ zT{%7}NF?WKp`AQp>d)-)JCE#U_u1-VZlkc;HoNjMY=As7s@ zT*1L*gVtKiw5u?DYPS$>dhJ6)j~7?FJ-FQU6ZJ2Cp#HfF48tH02&}Pz)dFLsm@gn3 zT;3e$QehAPCuhy)V$zIzI%_9)_GPmuj? zLiBATzFpamXNTy=c?NdQz)-$R7?Bu|#Vyrh#JDi@CxPb8zJlt8i@>xLz^mGT$;v`> zly2;#$a5ytNVXiieW2)$Qo2>O*3<1R+tx86rx%Decli$==AQF^vpmAoR0K|e00000 LNkvXXu0mjfW4KG5 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/report_disk.png b/base/resources.pk3dir/gfx/icon16/report_disk.png new file mode 100644 index 0000000000000000000000000000000000000000..1c856cd61593e944e09238a6c2cee7e10cb42c56 GIT binary patch literal 760 zcmV^u|ySI)$xo}?> za_FHfThhJj`M)!)y1Ken7-L>YP?_pt$X`6n=F1=cYufX?^1}RqJ{J3UFP&@z zECfL?sZm6*)=sM9@pvfG($ccT7;|1yt+;54&pQ5j$#EP+q*g1XYJxR_XwSX$w3G!2 z8vst-96|&vgaZNsoZQ_szDA8;W-G4J{Ce716A*!AbK_$I;eFp<0>BspfZNc}Fj7}n zH&}UjW2aN>p_1)q;jW_`Z~sC}RT&uigd@Cv23*T7n=wUqsU zAEO$8$8UyegB1-$AM!t|C?yj;*oTW|EL?#jJ$3auL-+@vJEf(KsTqgop6ei4H zEY=EI2UM$i0>P`>>10YEOo!2OKty@8ZJUOcD&T+xtAv;r<;?W~3dPa{g6#)Fg1eo# zu8R?iO9bIJ?eC7zl$eLYAzvQk(Asl2#3=h?9%!wXum1F)FEJyIwUEtb@jRFLvtd?p zluawwQ6HTH4*aalAvIN#h=QjS>hGUEu&8mvykvA^t`rPj{#@u;b@0}uB@3EX)K94= q=1oUSfD%DjgQzmS1APn^1O5Pr0d*Bb`9~`N0000Fu+SB7fQB(wh zKmdNfpU3O3FR9n6bx(yFW?LM)(cuM#(}134tA_DETWd7rfU%`9Ss=MUcwKe7(*}5qB2i- zk1uGwpM#!f*=R`>adwu?cYRS;jk(Tzc!pa5-%tD+u18O4qC2Xf>4JzmAXc#PD9cj> zmPQIePd8!CP=*zI1Hw)dY_GEEzXf-*VXTm&DS011zVX_L^0)8ccHG9=iU}(d*Wn(> z!>C3EN6l48Pm59_3;GNo&c|{B_6$7JdMw!sutt#xjAwwFlEOQphN~tCL#8&w#Kauq z3z~1q(fw40MoBC;o*w>)IdlG>aXKj16)Zb$Vxmd{%a;$BpP!F@3l^rJLA)0;b^@b% zC6jFgH7P@IDh(c{Wc;}p7GpbRXJ@0o#O4ASx*lhtE=7p%ZEDzbPcYM;iom24?jaS% ztCN_qjvKRw%nSZ4cwc%3@H#P8m4Z(7ZuByD?R}I8$5%ZT78bDi;tLcC#U8EX02~=eBHXF=lGptrCNRnI^up*XB(TLMJ44Z(P$%#Ob!q#T1>~_OL|8>GWv|h92aa9 z{ih?;wSVF8wbi6u7gt=;%4KDEJzG}p;qAaH;=^%nG(BPMqDp@klu}ijdLQ=94+Sv> z5{U%ocC@0D%Irbp!4@n#NPHkpOYK#D^dGaU6$t)gMq7NmrR|21O9Pc~fF9rbtGGLP%3{FW^mxhqYuZ%P6Ek$g&*yj-eIG zOqohJHFfOGwFt}FbPkXLB2$&hHG54GTQ*Tphm8dA>h>M+89Ra5!?tpUE(y z&c$%)5r{;hGrQy<89r{a*@70+1nj0U3>K#&7K`l)UZPg3_vrQdlA)(cOzM;vl%|7a z*(5@t5Q4#=Kp+r6G#X6^k_$#*D3a_DY)Q7DX&RfGo5=-+8YLzg6)@bAARG?!RCO*u z-LZgs9IAE?RIMIR9Hc@J2nAD#f`LK_B9RCW8SWTeMLS2EaTTp2tEgz6=LMuHsbJud z0$&>B=r0iScEaCZrJCpPURMoEmmL1-PB07;|7Stp4KaT}M6k6A!Eb58n)xoGv>7WS zcd+=ipXCH6w+kM~G5%79zUzmD;mQ^dDw^DAeA58`m=w{C4s3j{#+pfsxp#%Axt5|y zE|?mHK0l2YkTW0>vg^`k6(Z~12>Y}MujsJh)PnI=W2WIeEfjpx$T0Sz483`2!XXm4 zUE!OkL(p9d##0W~TM1^q7|gE%ShZ)FqyigP(35*eIK;rB14~2YST@QLn3aP0oe$Ps zgwW3dOg}yaDs#VPyWoBqjCG~x$xaB?f9T=u<%YbC2)S;8nazf+{v4doFJq=I2Oe|( z&U-)#K3+^kJRXN{xSZR$4S{bNU}mns{yGbmz9vK&8Znjzd4zjFQB-PY-ZAvvK8+6- zQsHvBuwYOi;(vnB>{ZxaWx?2852w=!tJMm--42t8`o}o+HVTUg~@9%wnpXc-b-uGnzU`3-*UT|g@ zo0_}${PYS~EY{64<|1jn77mAt-?u~fu^oW-Nf+w%`k6u@8ja@M>gwvyr|A)Vn;(Jq zaTh9;N=r(m5{kuQGx>ZTM@L7;fK~%PHXd~T2WUVVDHIB*)oQH<8-@{t98zrD@5JHZ zAeQ1{U@q&rkwFmX$9#l+-MHA38*g7^?AM8Z6TBRY)Oa3%mOx}M#nz zh*gWh`lJ+JUrX?Dpo7v${ylY!X;i*V;Q5;bok6)={&T9q+Pw}sAOdJS3JE!pJUeO5 z<#Nbovqc8bb7C+dL2z~$YohjM^VqvRC>D|!olijSh(k8_3$j-~kxr+P$z)EM!ImFx zVLQBDFU)2$oK7cV9tr$gQX9rVLQxFP;kVqu3*=*2iwR9~I z2%y*NDMYDM7ETPbVvIfF!JwO<05UKhj|ZR6he#xXU@!=e#{({xOJ5@aFraFS!OXM) za*3D%bUGdS`uf1(a3B(iXvmt>8U|9SG*1mwD%GXs{;O~d^x$DXhboiPR#sMEx7(pm zD8THaYf^K&-E;=0BjsO4v literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/report_magnify.png b/base/resources.pk3dir/gfx/icon16/report_magnify.png new file mode 100644 index 0000000000000000000000000000000000000000..aeaa889534234e156bdcec30b73b591b10d8a019 GIT binary patch literal 738 zcmV<80v-K{P)JgP zpi~!%ir7|Bt5jR6QQK0ZCTW`7b7ovzy|oJBfwLHx`JHcmbH-6s1_lOpm2RKDZl(&D z@ey|9hdTJbGvW02_pi6sK9F!G?O~ZbbC_*sU;J0K@B1Bo5ClV=ot;M-U-ssk7Xk`l z7|ux)5ma?foJyr4k?!v9)z;cm(zYKD!}oiAf4$_oE+P`gj^o6FF+uWKZ$8teAW;Iq z$xGvifI?ItAi#;e+1WN?g4X?bj^W##yRm=>tXZ1+DG=Sk(Fy?8+PMV&;I({9R#DYi z0ac!lP9uPdqGAz^JaAoC{vbGj=NO8&@5Viz+?V6gn+Yb%HOjRH8WKt7r34#RF(y$3 z>@304tNBc8#Hp%?2p8^uV8Q$rHmu0vCp;#;)hU*0JbqhZQ+rDq@O~pWh=-wgt1ouC zF_or0*F>@AV5$~%JQlZQcrjd|P$=Mep6dodFjOcMj*R!7qx|GNVu?pouGUE=6BsLq zC^L1TZosHdE|k}>@gRw+&tz7K`>;DS-0`kjdx88QmDen$Oy(5j4`A|Se4f3J2wko zOJhvGAEb5pTDmrm9dmve*0XA1*Rtm1)<{9 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/report_picture.png b/base/resources.pk3dir/gfx/icon16/report_picture.png new file mode 100644 index 0000000000000000000000000000000000000000..3a9a7e5eb91319a532f1c796740c70692b8335eb GIT binary patch literal 733 zcmV<30wVp1P)jdqY@m5y1@@iycWVf~UiPPmZK9+AcIyv0)YE`F$AZQJGdwa**+S<<5zV6SY>Hz_* z^@>9093rw}pGYJC_(x#KcXx8|<_iX&ePnXFNPa;R1U{j*)C7L@R^@PWue+86@v;8Q z+O&WJr4*B2iX3m>PBNMLFMl!A-0V}AgN}}loz~iJ*LVV78Gbx`gi?yaq9d71F+Q`v zrSc?V8*qfU_!M6Y zC7d`SV^}6QiLVTW2Ngj)<|6{dQbeI##>!6?b;$QpnF1k5rKT!)emAqWQ9xwr$3>u6 zc1+Fez}38DQJ0u6Y@@lUrrOG?;1oWF!r%}9p|&^&^S>;6nl92Zb)Hx6vdka2hS3HA zBJHXIZ}?88E-g4qMIeGg82fw{tu@0@M6@wR^s)o3HOKc4BeFtp8V|$Vzz|9))~8~K zjkt2Gk3SD$S(eaRQycS^37+20q|y#-rJ#AsI&KYp;LB`@ARZ7!mU!F;sRqf+zU`_e zF)FX|Fic)L!_mR_IOnj|VvHdSLvpzs4Gj&X)9Gp$m8#5wF=kiGoBJP=8xn}X#KZ)~ z7>qGXbKrR%xm=EHHjC$ZL{U_^bF%x17Y(;Yr_2drFbQ=B?CYbj<)Iue4Y zjHuM+6fIggQwO;rx(zM1NUs_(1KGi;_5Ap~&-=VA0IaF0sdJ+( zBtEEe@J_TBEEenV2D6)LPPf@?{?FDi*sT@}7o}lsZEZuLAu5$>lhJ4tzP(+F@vc$~ z7p5T;3NaE01mO4k<5^l-!s_a348SxP!4Sb_H2Zu$w5!X|!r2OK&NirsEPR=p!^+AE z(_lzjim`_!7!t6tyu3`Orh6Whl?~8ycR+JK5!z@iJGmLx3oon#;sz5jgTYH|gu`Jv zs;Bd)$~%EOWCk8r=At}%7pnRDL1rc+7z{8C1{+K8sk0aZ`KdIWO4XC^sFsoNIgAL- zn())ofnP2YdYTHNfMDdG2K{-d^nfS;b&a}CLL;&3M?)z`lEn@ z>jw437=1vZpSLI8Ox8aKCpQmuIz6;XA=+*Vp}2Yj#Zo!$wzeW6A>jzqU}6Nu+!PvM zHk+Z--GW3S0iS;nhOS2#7=8~fmkW_d1esicqsNXL;s&N#5|(xe`Zy`{0KeTk1IsfV z)Qx&5mF39i^TFfsP*6aiNGwISp$VSW(-DS&Eo#u4lS~_U2kP;%mW#_`1@wA7G#U*E zfC^9bC`4LA3-Q+eGNijse0UKYlEHg}R{$a=DDYia;QsYl-3-7Thjm zr0+cYm%;0-Bt#++`X#7AQmadCqs!%j*XzZfC%y+26%|R{oPFrKatN<7li+r{F&AA| zr_+gCR;x7zpg>fFsasCf9oVjsuoKDu`Od!qHK~iHIh0CT P00000NkvXXu0mjfuTNAF literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/report_word.png b/base/resources.pk3dir/gfx/icon16/report_word.png new file mode 100644 index 0000000000000000000000000000000000000000..995134248551bd273d1d82c8eb10c11545a28daf GIT binary patch literal 731 zcmV<10wn#3P)x`$;*%QE>Pm-#2tuNQAW$Ppq@+uSPM$2ic=BSMf;tzS4LT(D4twpO zC5F`@JQ%)2wPk1+YwO#tn(OYf&&>QgtZpeCoZG<6@ZmqdpAr$q$Hy=J9=bQ6my_uE z8Cv=h_3UmfsIjrJ6ULbLHprK|7#8n$a=!P|u5O1yq54of9#1qjHg=VL?(eIJ0s=u0 zY&&SJMMSpkJ6c=d?vho>Ndh+qm9 zfWQ}iZ5Wo)0aZ#dHD_>?&~mzVr{F3sn#|xZ01^lYWOEkB7cQKMGLcwg%~;N!+Do)5 zvV8{g{SR3meS$R<1pzoNn1ba{G|Z)@{RmJgn&yTWuA_De+Hue<4-BJ}BFI~o(mr>( z>p&ov*IaKuT>8evv|oH+D+kWVi@u7O1+$s9z;f;OM{?^qyfP1KL99gt#0u6b)V3rR z^5qViAGbQVJop`JEyftM*7&|pDwU$Tx|&!lR#GUXie1oJA3yo!<@BC?9wIO^GlSL| zt#zpfj^mI@rI?+a#c>=8g<=rYR!KUJM9&?ph%_g&!Oz}r%agmU^B=+0hDY`Kt<(Sj N002ovPDHLkV1l*bNUHz< literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/resultset_first.png b/base/resources.pk3dir/gfx/icon16/resultset_first.png new file mode 100644 index 0000000000000000000000000000000000000000..b03eaf8b5416fa6878165d95116e73003f8445f5 GIT binary patch literal 522 zcmV+l0`>igP)ufs8f5Kzx*fI63}@)AAFXgQp7K#X5)&2^7g z_9O9^7^ARqyc%qAP{1M7?|}io8xW>dotf=a%%ZSXBBI&Rf<-t`#(~H!2g~*8&15{# zVXjXMwHZYVJ6lk!gb6?r$g;SuO>QI;yeQ51#0H@Z6sk_ajqECPZEqLq!PMf5MQ5gS1i(Owi(ut_CY*w|Psf-Iy6=08Y` zHnsuDs6h)+OwcBqopImX_v1c`5LkrSCWWWFUvW71z%eN$cB714YVYtd`}$X<%JbQ) zM;;CHJDu;#-swg0iul07{S&4s!M>4O+`c|6_tW_i^y+I%|aPsIlEx5K=^ki~8LwqDy-)t}thx1D9 zB6|#ECQ%2a60OQQ<{6-)5|okv)6E>1Xpv+@iIv@MJ8v15 zR{N~1_2z$e&R$WgNhIQelIl1rK}5XruIN#GDZA_4bJqcqID*^mXXFcgt1K5iK7HPL zwLW*@#tu()#Cyd@CHc^75Ul6pYT4PCpSeBE)hh4bY>IO8de(|Ml<%@O-40!dwX61{2C5s-llVw2V@@N0oo_PPieZ!0Y2~+R( zk!(QTf=B;X9DnzJ@u9c>OP4(U@7{849!UlyO@H`*;lVfmCvAW6f9CF&{}ZR*{jXDW zb_vl21ozzrYJBy-Vb$aRjjJF3@7nm}zjw#A|58cE9uZ}LbIY~=6ShA8U$XeY|MDdd zfQCH!?_7WRzhvaG%|sbsT7Kz&`}!yUix%Do#>T_{_Ei`DO9UTSBkH=Hg(w4*^UnUS zTk-IJ<+2C=ZObqG7Z2FGlB7VCN;>(!bn*TFHYMl(i+Sx`L~=ArL>~EXU3lidsO!!J pWF;gqzXSh89JkLNxXeT<1_12n>%V}Y6R`jQ002ovPDHLkV1iLCz99er literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/resultset_previous.png b/base/resources.pk3dir/gfx/icon16/resultset_previous.png new file mode 100644 index 0000000000000000000000000000000000000000..18f9cc10948f025fde708328fa704b520161e5f6 GIT binary patch literal 389 zcmV;00eb$4P)K{b{Xc8(tN&i@ zH%T)fYQpV#rAr?FpSkE_eXe+_wJd|K3f{{%aMTC(eL? z&YO?2=RWv9b;pbUjjJF3FIss2fAiYM|D{t;5@!?n%vQ}6um-u(1``H~0!(`ViJ zU$yMvf616*#2KJfaGFIu@9Y|n)@%Q3RzCcnHskjH!iD$#iw7MbEf6JRj;ypTzwkeA z{@wqXv+w*Db>B;RG>UocU1Xkp@_*9QTmMBIcK#N@1p=a9KakdI4{r9Fsj0rE)+ zb~J|8lW*Tz02$`Zaxk^6sfOa5!ghcM1=puT<{WmU!JK!6{4kb3fZrJ*ROjE>@quHyr}*Cr;=Aa64! zj|O-=Sx^U(hAq-h=kq`Q2V>dc0LCnFFu6l&F;*d8IpiIHH4yNNu{%yB`v73}L;K|S z5BXjfZJO%>P`FNNQN^m$1zjx5c5Y{17VpEWq!t0|e{#P8+?shbj%;~D00000NkvXX Hu0mjf+-WMY literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/rss.png b/base/resources.pk3dir/gfx/icon16/rss.png new file mode 100644 index 0000000000000000000000000000000000000000..1dc6ff30ba5020600aa4ba2646beb9eb25dc978f GIT binary patch literal 530 zcmV+t0`2{YP)8MDR)G%QU0LxY1jsDL`i z5Y)<<0mFa+Gyv?I-SF1`9OhtF)?#(7@ZwPg0IYohcf#rgRl*cR36-)JAyh$ycISTR z#|RJ*0Y`3-+O5RfdxRPJ@Fmbb_UtP8y?FXu?dZjo$& zzrG9Rp9<^S_%m{rBJa8vxT8 UVM82oKL7v#07*qoM6N<$f={^a^#A|> literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/rss_add.png b/base/resources.pk3dir/gfx/icon16/rss_add.png new file mode 100644 index 0000000000000000000000000000000000000000..b590beb7384ef1eceb91d38b67f3f29d7ebcb4c7 GIT binary patch literal 649 zcmV;40(Sk0P)_`vtWfF`j z0<2B6iHB4fl=M^yJC7s$OkB4XF^SV+68F!}^Z5-pSkKZ)7dfJ zWJl?2zDxJhlca-{tPoI3*~Z59s;f1d)?99?+e2nUJu`EYjJ+LY_Tzl7TIxDCwpVon j=YTRG2izRLk?s5g)J!H~cfFa;00000NkvXXu0mjfU zi6qKEsUS((2z^ne7sH6u^xpT*$7wNF!ypjufnm-JGY|ZJ=Nu&>loOgVqilfTUekXx z1h4^|1sA{;!TEUSfucYP27p~1|NITBmk;25%&jlw4qn_X0RR?q5CY;$51d211M3iH zboWq^PPG;;65b4e59pTjU>C6uFOckS$9)}J0cfm^fFPg^RMkOn$lMhAa2LAi zB;mso)RqR!v0H@6*ASvaQo)cfM13Kk0JZM~@^KKVYVh|v(5+X|d)k=nX(9J{mc^MI zCTpl|_)UE(7*ZE$AwaN%vFqrAoyhw^lD6C6Et5CTF_%`-*m05d^?S*`8)9PQDW*_F zN&gO^@i@Y-=(=-=jZTY=?!SC6O!MhJDnAXw^ayO+#1B))#Ly^)ynwYRUx8XKq4%-& z63s2n7pT})4@W!yc3|&zia|<%XLnXQ3olSyy=RPKX?&3EqqC&>8J2*B`2>?_)LN!- zq`jthU3K>I&dtskJ;lPTdu`X^&)k{Bt2&>^w7@{?kh}5+(yKTs Tolt1000000NkvXXu0mjf#S9}s literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/rss_go.png b/base/resources.pk3dir/gfx/icon16/rss_go.png new file mode 100644 index 0000000000000000000000000000000000000000..43a86bff65d0c81eb5d4ff8f95e4e825f9015a0f GIT binary patch literal 635 zcmV->0)+jEP)^cw4_Lf`NnXu4)qJaOz0Jk*jN=Gk2DWh4)N< z8s*VU4f~P`qK$rI>tMXr-gv6&^_Q35oN{`3$UXxb2jm8#wV)MM1r50$LpE2g{{bi; VQ8S@)tH1yN002ovPDHLkV1iVr3a9`8 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/rss_valid.png b/base/resources.pk3dir/gfx/icon16/rss_valid.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d0b0e872408ecad6388a132fbc95aa4ae9a558 GIT binary patch literal 660 zcmV;F0&D$=P) zlTC4I~z~%t(2;3ZV$IVbTEK^K`cbf9DJcWsEZG8LjgQ3BX ztk>_fsZ-qa^*zkr^JiK2KaV+&zI@_j^%VsVuFdVDQY^v4>l8Vx1;n1LCn5~d(Z zsIW?vOXDVh8tp@`Vfq3Xjus#w0#+U)DYX$V&J$*&OAmk!WA_e|ZaBm2QW<@4n)vV> zM4A9qP=jzNO&}hhB3XTc#2Wb1b6`%|br9q`a_bOGJ*fn|_k1ofNlU#NR&w&qt&YqzwPe=XD1lS-g*U+YebC>)k^TqzktpS2p6W z`Y3jv%8gZP0vejr+`$EZc9x`b3w--bVcS)b@+9o#4N5(I6qfBm?;dXg6aQFF90*an*tf?f9 u%m^eP3upiqkd2B87`f4-l>F~^Zs`{-O<@5o5}gkK0000k7R5;7c zlif>`Q5?tj7Yw@ZCMtTF^Q|ZedeJhM%QPCR*bs8V79p$QTo7e94yQNXRs-{0?hOn_-8n0AMO@u1Ts zNl8QzJs1#rz%RBt?ux>l+amAvh+J!{$lkaqv}+Erb-6j2xp>K4GLQnNB*W`hFg*?P z^AL@~(h~Z+wfcWEXHqV^Tq-#z$7Y#o0;yFxA!00F}F2dX# zjE$iOgT#G4*1TR6kB1Gnn@>$meCh2a>c5YuIvFn-R2W@>4@M*m@-|jiDV?b)bccgA zyPfsMM!rjy>+1O2)5Eg29Z_*2p&qGnmS!OH?vZ(4>QB01d>j%9n4QINxkyT(Dos?I zjaWF$*IQmh`SF-?xU%xMEfjq1=6qY*g&lgG_cXv$BGoIWyfO5 zp>pdV*O+y=&6@N2WWFo(%RtT`Q(H^6zn^a%epE~Kx^mEJ{c8`luC$nc*z9j|4Ms8aJK-la*? zu}sM&ls8IJIBTw8%#^`KxVF<=?#=zao!{!hU{cUc4}5tzhx2@%m-Fxd@cu=-{{z7G zcFU>0QV~u$otEUZU1a-OC&^y!AQ?tY(ygr|b+Lsco1|o`K@v%vt5f6wG(bj`z|0F^ zejZp}2K;`&=R@xGD@4Y|5FH&wd}IW%2M-Z+I1s$ukImE7iFo-b2?uzKCy#*1NxZPNzdqqd|ya5LK(Op-|vmVZ9X=X}9uO24{Kk}A!B5JXr!qbIp8z_8L}evXRx6$w7guhv5miVSjlA&GurHb?&tlT#n6(v-{&G z&-l~YZX~a3p)yv(^}zv`?|y#1w%JRt&vtNt1X7ZUi&z*Oj!7dOpRh%pPmp60w ZKL8&#%K87S&;0-Z002ovPDHLkV1m=DG{pb_ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/ruby_delete.png b/base/resources.pk3dir/gfx/icon16/ruby_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..30022630d81b07d271d8168bc8e2b67290fc621d GIT binary patch literal 704 zcmV;x0zdtUP)iMii@3{=qhJYmGNO z6B95x3hnKL%F1wAEX*kiZnK#MlZj!2fe$q`IEqUU@h4qjfmpTN`dY2EgY3raEE})C zpHOx-b9y~rGBf!uF_oOm`|4_@lmbNTiFwb#_?(R$NWW3i?~_nfC3JMa{5*_|pc;)V zN}@-Kc+%5x+U-nVRS-vxJKYE3;{Lcoz)}#oo}b?pwAo;A5XQ$*<>*4E!<&}ILR}p* zlI%Hr%<0~LBxchy`i-VYUruh%vKUS;eIK245Ldvw}Q5*3@~ zVD-Yq$dz<`@7nDSQ-7tybO?#sqs)B8oN*$8uuoo~2V~ z9c$K7d^fE0CGJpHC7JsMutkAAT3Sk^CsjN3*My0q35TTLA?bG}JhnRgnBSkLau?zH zmf|Y?y1b2MkR*S(2DiklMT@L|-jcwJ+}%|}%D%vyEt;=4x8qc{@yrkr?AB>-ZTZu@ m%-vfdJ5K+)f-6i8*M9)_HOV}%zz`7t0000p`gJ-s&X^#FvVo2#P4DDKuuwP0($&5u3Gi3xsSB&b7S=yXf4CDeP%T zi085%<7O+R*T-!1OkxYf)Oe8PJhFf|3Z zT)^5Iu)GXROn~X_MMf$`RxCzAB*G7Y0H2$h5ZCFD?0yMSe?7wz)Kyf5I<$7M#1FH8N)$3v2_5+iXKrRO? zE#aHNfPmMFOh*U8;V^>1AYwf#d>plvU1p2xSPErnS8b`Y(|x2?0}Bhl>MHzxKN5)q zLZJ|~WF7H%96q0qF0DdGWoWh9v&SMiY!lQT@LJs^mAXo>F+7Y|EJm$yL8H+?uh&;) zM59p{jm8fr_F(@}OYPnRj{o<@d_K=k0@Zs^xOBC}VzKO{(`k4-9t;i+o?MRIJNGU) zsi9t~KSfQo+wIu8c!kHVnayUhMw7Byt&m70e{R?p-qV}2FJ5IA7Z(u-1TZo(vS%`x zh?}Mni9{fm%k7ll{HZl{(DJYZ>}^;%?7^|IG0e@)u>?>k6lYE)pc-v5nGAh>eU0O^ yjRqPko!TlC3K>41Kl4|QNvTvqAYki%{Qoay0^pl|RRvxE0000S literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/ruby_get.png b/base/resources.pk3dir/gfx/icon16/ruby_get.png new file mode 100644 index 0000000000000000000000000000000000000000..f5203c7e94b09b06f5b6f42fb84b126e323e3186 GIT binary patch literal 692 zcmV;l0!#ggP)Y=UYJ?ASrjeqP`A=ks}gya2C%k=OqLkPGuPLSKZW zHF@$4lE;uGt!8FOD{1E?w=P9mPE3@R&YqK8@oH)Dc-)-x=rQd&KolehIqB_z{(cx4 z0jm|p$MHOU!dz=B_Ldgro11Yo+`wiwW4lz!LiiEqd}vtQ8sHT-8=5%;PPS|%U6u)d?MW5>JPEPJ#EhvD20T>-c7S^SxD4fyJ%$iJm6vYnT zpb7g9zdgTQq-(r*x zmy1e}+uB&EsllFYprlbP7eCIWu=fJ-x0IF*gS2oca@+j=gVtq39!`S+V^h3b^eBg> zH}y1F>PWkrL}YE)`|yg8Eq_dy6d39w`W>vergA0TKIP86pU(9mGj%UbWZz5YKv}RW z_@bicuOq9fkHS1yjj6w!*sGBQ8T~>xbqm5WSDs&{{8=%9dA@A=n1p47WfVC+?9SN! a6Yw4MW6QB{x)Qkn00000x$iEP)rl-P_^Mu?M#=uC#u zWRgfl1^(vp$dZ@wYeC?I?drV2_}Esbuo$wlp{NLwN$Bgt^*mf_ae-;yCtO|4g3rC= zx3!O0Ay2s%Up0TV4Qp|us^d4wE?iw7oY+?b-WV<81??Y&0G zJ$aoU8Ug@;%U7nXl!x^|;=Yc@p}!wOA;`)iC?z4K@U5b-U_Ixz#z|y*hw?f1?XFp~`}D>*)(C`F2(4L}UqX3dC9VC9bPTo_Uy0n8b(1OQR};Ox`=VCJ zJ7;RgYii1lp{+q1jlnXK93(HYl-Ipac{lLF_)6ple-$I^-rbp0Rn2iFB6}T zMxl&EYRODymQAa-lah0RH+@YLe>5@s*^@zE`6#Ve7A<0Vw3rpSF+y$@OLA86KG95b zPt(|(V2ks&GVQ+}GrkZABk+}AZ9$o{Ew+od192LDrY==^URH(Uy&w-oIN zKksfB5{ByGdfWBe7yd=;f|J(94SPn%M(b_gkNg`)>s4a^*@puF0000uOV?{sfmJEOvVyH^4y)cgf5dHLYF5Q%^>gqd5u-21$*wBhAR zB_jOdZ{3_P+COI%7ca4wFNeH5CbKW$&keRmzkEP7aJ}9 zaO#ishFM)}q93lAD_8lgun@=h@vBBsFm)+G<{ddBM&m?a)V%4D2^D4aN<{dZw`@he zXmiP_nz?Yu)F}k97~g_M3Rlg+vSTP~7!t(6WN1G7DWyb&f2HOxEER3;FmLk2RCx#F z1d>}-q#UaUW#thX&D--WeXrm4u2&+$|9m)9wO6@A50tE27ZH6E6(o7nkVxCfFl8&n z>(SL0A4g;`kw6fc= zhZghZ#*fsC=bhU&oq2zne>e=_OEi9~H*sfNrYr5WwtlZ$f8yN*{^KXl-Z$AZSrFg= O0000Z&H5% literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/ruby_link.png b/base/resources.pk3dir/gfx/icon16/ruby_link.png new file mode 100644 index 0000000000000000000000000000000000000000..bf4be526fb1190cc7f778c5ec7894b0db5b367e1 GIT binary patch literal 767 zcmV5*`Q5eUCpo;>bf5H-)x*6q-8!ArQkJhH?Vnaw@-Q1A1t>wIFB5v4Vq+TQyi3r{( z3L=SKNGYNaH5GrBOp}2c&b=pHP3PWyJ7;%`?z-u~7apGH`+UyxoRbA0>tB@he*jYM zCkCoxD#9eV97J%~NV3IBE}Bgw!8MTcx;k>Ee@Nn0)#R5-6N$<18q)yUP(u~N^c1kL z0IaM4+uOj#280jq5g8gnbZ`(S0|Ve+y+*jZ8{uajoJz}LCq=~?2Ka=xZ-9vjU}OYX zUk8?#fzeS2E*HXPGxj+S(S`;b8IAa?R%5HH3)?n3i1<#J0rFE%9UoKAeE_`;dwWQq z*;xqH)!0`m@m-<752~HgQfzv?*x{N$@^2sTx#F7i8_<2P(S0X{b`LN<4jdc+OG`)@ z42aN1o^|Z^@@|EqHwp?ee&NF0l%1%rf0t}+1r`^9wKb&Z=%lD z`Th7toB5lCq3HEI(Or_)WBl$0doayhhGZCWg5 zIaXr;=FI@)(xX)#?RL1`?sUv@tj0Xdn*qql$+<*FEKn#E xyBx>GtX6BB>b$nLwvMWd#wRStYRtpDzXADfss$&H-+%xB002ovPDHLkV1ii!VgCRC literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/ruby_put.png b/base/resources.pk3dir/gfx/icon16/ruby_put.png new file mode 100644 index 0000000000000000000000000000000000000000..e026323c257e45d5d4c8fd0464a47340d1f6796e GIT binary patch literal 694 zcmV;n0!jUeP)31)X(c{M zhz)p)O~Px+7wZ@D#M-%R;V~M-s$MTv(oYF@s#+``Pg-ytJ*L|fkOYl{i~9pGGz4Q~ zV6(yGB;Lo5SZHm<(bB?Vb2HAmdh8Yp_G@J<9X#S%jEGFy5O_|*UFhk7jt-cZfYDLt z?8IAKj6ElZS)&n$!N9yu$BV>7-d0s%%P&Oi-e=zs2=SGep8BdQLB7V!44Y?g5U*Oz ztV+elgakfIOh-rarlNvrV-_N0@0>Gmw`Ow&GVeB-x8GY{2Ho8-HwRWLKCPAoNpwmP zXM8+Um6g2DFd`ItrW`w!${)6{mXj6W$;|9qFD-@PVHh9BC#{RvSX^;&%$v=8kYs0Y z*py?3V%JaCxT4hsxHV~go|4jU0&)hfs3=xyYB>M!4B7oUGP=^xwWsjQ9xR_o4)_wU zda!!sD!%r1)~c&<6qq>MtEFwSftJ^Gq&BM9vPesZW415uKV(}q72%d-nb)oFP}B74 z7IoHIv`wkR)I>&X*+dZ<5hU}D+_;(O*0-g2F81bf`=y22XJ!hzayd{Q?he1K9QbWj zPq!ueOUt&rdj>2cRhWmalU|=fSc&4DB0tdok2^0dkLemuqPdeyXi>2BuRfEsJfbWN cdh-3rG{ z$cl-P=->hx6#}NAmbP5myY~I>{qOhtLMa7Y{qE64eE#g}(xpY)TeQ8l?;Upi4EuP3 zj9qNwYy4OP^j-JLi)W5q`snr30AQZ_=_2*h-J^Uqwd^<9gC_@m_YruehOwSPa9@O%#PST ztn>RnbQXoQ3&2p_*N2(YI zkrMO}==(rnxsJAW59QQs0L07JZk*~;x_q%%{cN7dr3j%I4jC^oS!R20 zp-X8Kpw211iFbazd*AM1?Vu^zTr_Qvx?Y!ieJR$aQy;v2#^ddUoYEFRo!j>1ci(tn z{K@;T0)Sj-bCEg}zP!0%dBFa`LT=k_fI7GB{l`yczPWYR>anra$&%HTk?G3F@#Ue> zFdEg-dzaUZYPNRv<+lA7pzgcw+uL{UoxOeM-g%tFNu0n5OqYg(!P3&eWMyo1vh4Ri e9{q`*0R9JiiaRV3rbYDt00009Gp0rM-&EhljN^i}(|Pq=@5XF~~)>U!;+BT;WiZ;-?olqd>fK_MstEkar}b9uop zSG%(%K&q)D8CgaWKtPPtDOv9I8!SQz&9K@qF)=0vTF8Vz6y!_@T)cF~Uzb0()L$?a z`$c#8#_Jq>ql8oq?5#4M^3MAs_Mj^9a~&q%&y!>ZY?Ffij=buvY#%T_TY|PQcQN;bwCQWy*nR;m&;UD z`|<407yq%aQd%Bnb;^cyP&KV4wU)a7>4a6Dx$h-#bpLzK{Pr$B8!J;?KlH*=4~)Nd zXfFUrnL1@v!}G_xF3kSm{Oos*9r(bTXJ0f{jKZMUxbxsWQRhe^WR#$Jv5>jf6w4x#gTU%_MMNlkNp$oSbvBp&uHw9M;u0-4@=t5BI zP6Hx#-C_{5RMJ z0_P+Xkumexn8%)S+Y)#l(gR;YJP<6#1-=jjK0LONWPdJQIR8uK1HpvVIxBIQ2ztt+ zqoEx_X9S%QGMe=~(k#sebCL-an)%CR%a7YtUOQUgv+G>~?N~XSWhx=? z@$fx}0MB;$`JWcQ-Re{XV~5|{DvU(#*+NF*g)j^qk#b~G9_O!i*y&mZVZ=a3;Go(K z`DkskYn56Nhu+k@1Ke*uY|x zI&k6j$JfNe_a{GH%=n2rZOz$Z8R9V?Pe36hIk}jo+A-`;dt9vyvBu#Xm@veu&@v`| zzt%mwc_$nd0-sMVx2d)b0!MqGxmfCumx7yB#nIUWvA{!HOMfslMyW1iV&nY>zxwyj z8^JfLN|kT z4m^Q1mhO(_r4w@`V?H=YNkOf(i&bHT3Auc3bryK1_{hDSetLoLN{VLB^78ULiNFy^ zkUqqG$fjVkJj5tfWkOn|P5`HVEp5@-mGnc0wvJGHC=+39MC2TWT#i?t*~fNch*he_ zgtS^8dH$(KlW)EF1b4Fzv~?&0IQaNdg;W5&{t&Bmg9&N1-rBBr_;Rg8ekw^mn;@T# zlS{|Rq+-Nlg18i%UY;i|q1NnSwf>I@85#4U4002ovPDHLkV1mEDi4_0< literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/script_code_red.png b/base/resources.pk3dir/gfx/icon16/script_code_red.png new file mode 100644 index 0000000000000000000000000000000000000000..8fcf0f09ae3046a7bace82cdd583ebcb2bb58beb GIT binary patch literal 868 zcmV-q1DpJbP)r^f`W}XqzY0MJb1LFP|{o!^ss14Q0vK;LyO=G zl>{$>EqZ7VQmVn=L0C~*jNqY3H8#?%q3Q0roqd^|`M-KFiSY;D>*w+ z0Uz8~N>7H;5K4nIhJi8x&;^=+2HHRi_#F7wV{=BSiHAq?ldnB7%+B?NDTcxn+mRj< z61uVG&t{Kr{^%b7syl&^Lec@Cep}-^4xR%E4^qC%y(yQ3>*6Qik+BTBin;Qqm)75R zw*W0=p=2VIfv#`}By>6vK?FertpVKXX#ie7d!5Njjt7SP;cXxv1|$2wnnxX-rXOi4 zCubS@>|?^9Pd7I7BFjL40UX`or)zDNt_SNbfH*o`o?ZIlnVdI3Iv!zck$CuY8J#~x z)b7%c4Si|A!bT_N!^PE(7Gl~JM~)mcVf5GNuwOLw7WHHApn#=ARm6>eq|;~bu^Cde z?}?Oyv7mj85~6bc<;NCXGl=HnedB4fv;xOx>Ez2eF6cs;-(PqIez}UA80Vh3leki1 zEvPs~i&z7=CLFw&__`LE$}XG}Z(?sXaIqwVCY8B&QG4#jxmcq)!WE?ipr}qVB!Avj*}>Ogl)r>xpM?l2gvx)>cyy7Y%IL>tOalZ z7KZkUkERae#gJ$;z;SV#4Z;A{PMkvKieMq@xis1Xw20TYuIEiv&kg}^KR7u~uX={> zmIb-4=EqMikoGOU2g$_06|%5e4^cvFYy(<|r-0{vUS6X;@aV-BsV%W|5Xzvm!B|VV zSmdRrN4ePw(Lyx-1EhTP`6nOBym9#P|NVfrAhks(z{2T;b+SHmdm&oN)=psUW;5W- z;xeUthEgF-DVL&{OL0dwNh;}*@>~v0jga!7@pl(3<&AB?D0QxOd1b72d1W_n*JgKa uR!k>-Kb`g|yI#9! z6)lXSPy)q8C1lZ}g3^41=HNKqnYs7QJ?H%A@B2c|8SMY^(nC0W>$>q>gSs`STXowS zHf;~fxQ2v9EZ{R7D*@W3dHBBBHM?GWY!d+JSMBtmYNr=h)3&N+d6b;Lw&L5f{XIBX z0<=xDd8!-0r5i~n1ZAKo8S6whk3~g{It4qoP1rg;x#5%3mk&jNRM%6JB~8n674&Lu zjOeY>TV-L${7M3Ee16fcxk-1=bT*X$sjfGy?MD3({naGKphQs+3kpFIXc5wqAI~j1 zbFp{11V~l2d3vJI8#V@`EXJ&e#1s^fLRJ*Wg{w;=M~?r!g#9HzQ&rnHPj&QGvj#Fn z3Svg0kd--VGpUm_RWo<=l}E2ffK-jP&rXl&S6PS@A&7_wfRM?VW;BwjQGycozWv=q zS;X#GC#q5sWn>vi00A*lr(~r+Xs`q&G^1+MA;g07I7@NDx@V8^d@28HxbNq=; zzxe*f?K5pkhju@>PI%T6esG3%jS_iIPFg`oSQ?CLj-`b*R!!2d1>j$2D{N9N- z_dNmtQl?H>)o|vgtp>k-WAdw)jfVdjV0o#K3YUx7d-mS8etPnmh2`4C`M&w3RZD|f z-DE|Kx}BgKTK}9nDt3ap=<6+H=dQ$*8t;dl`wq|GAhu&8Hex;2V|u*X>5Pwe>`ABX pxbn5N{RLGS=ZoANdGc8E?*HisN=owtMsNTC002ovPDHLkV1hpQeRTi; literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/script_edit.png b/base/resources.pk3dir/gfx/icon16/script_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..b4d31ce282f378e5b94cd40680d283842229e491 GIT binary patch literal 880 zcmV-$1CRWPP)dH?P zU9(eZs5A|8t5v?eTRRMlZU=heApt;c-QWm;Ex@uN>_}2!i6teD1%o>y^d_S1XRa-N zEVlrobv$Z==R-vaN*dOiP;xh}(13rd27nL8<{3^$d8*UtvbO>4tszOR2{qRsrN9O( z3#0`W0!x4o2vg>#nIhNcON;jbrFs$(i&Dd*-VBg3z>*-1z>;7Qu%r9~e~*90+noc{ zCV%7=ogDig@RaK7i93|s01qGl%Lrt!v323f)kR;ImtNTS&iSm|tlwheV@t5403k8+mq?kbBz7Iez4s~7(WvsntW4bC^upoW zL+_1G1IUA;W1XH-C-(17v0M(ATQQWfmq_ZL>3(tqwR{#U6woa9k)QmX+`va6fx$W7fs9{PlZoQqK^zXeF6_0Y=) zo``&Le1wy)J;oj`vgg^i2{p0wZPdg%Emnhs7DUXV(uFJOraKqiM8$=I3#~g5 zsinLfkEQ%6M1VxHcYm;Ee*Cg{jbI-l!ye@3hJn(LR@I1UqL;$#0T|Nz5 zd2nc8vKx82ktgz=UhEq{3)lo4unp9JPk^rj?#9RQlPAi1CSN^MWOq8&=eySDxBKp( zji41e?rgTX`giA9U}iT^$|V&5%XLRWDFOv1fK)C8U62)K_Fq}nj!CBztsdT?o^1a z9Vz7!H2OjeSOM!4)`4pLLT2e5Y}mpJxP&9NcC>owiRkmrsu!X0<8YS#xZ)9Io~& z!>UepZx&_G$m{7Ncig zMh6C!ID{S;<3ME!Jurq!9wEpaBbhy#*}VB}NmVXfDF8FT2(S;>_wM+or;J2eyeRR4 ncn{*igLkoLaaMWfMP&XzP&{b)e?%0|00000NkvXXu0mjf(|U^f literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/script_gear.png b/base/resources.pk3dir/gfx/icon16/script_gear.png new file mode 100644 index 0000000000000000000000000000000000000000..56fcf84a8518f692988061347375c9f6ff8d0dae GIT binary patch literal 861 zcmV-j1ETziP)-~Z!n@9pW{oO5sFQkR#oNEERoq9}~OLlE7(C>^?38iHU~FCGf)7!g^i zr#b|KB0a>q#9E#VC2d>I$+ouU+sE5`|IdEEpe##p>ifB)xbn@_=$0}CvEq;yxiY$Ba;K;UP=U?3g05+4N(N2oSY9}8}Qr5e<+2svC{=In|=VE{& z%bNW?0hoJ|s|0~KAd2a&g!c4?qA*m6I5b-GRHHul#pL5pLx4O@`|B}T!Fm#Cr9A1< z>d@-2vc=Ly4lZ7Q=-61@^Fx(gF+iTCgWG#Tn_V_LxiAdGh$6y>NFWL*5aerqn_hMM zVe4@WkS9sAQH!*;GVN|D3`%4zyI{*%a_aem2=mJ zaOvo?dn~M#W*2kyDxFqK6h)fNrs3gXwJQC6lx1LjecjyLoayOlah@b^;KUzyXRL0; zHoB!WFBREABOCJu2N#TujhP((+Eh^5^Ym^jD=Y5Yx$`A1#Ce(?e*3i-Y9F6`2>|3J z*S?v;fQ5wxM-Cs<>2%D@%xE+k@LsJ}dq2+8bY@|><=V}=2Da4<^j8hkdo}941_p;* zy?WILAD%V!`=rIiMayN=ty`a$S(e?rapOiF96EVr21Po+|=RvfC` nv$VA2&+^D$IC=Zp*(vxR7Y$Nw@UeaB00000NkvXXu0mjf2&J7q literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/script_go.png b/base/resources.pk3dir/gfx/icon16/script_go.png new file mode 100644 index 0000000000000000000000000000000000000000..8e154e2313cb8c8e66baa5a2b22f20a9186a51b2 GIT binary patch literal 839 zcmV-N1GxN&P)z22yyMI`&M<>aiqax`m<9PjBq5ZbMGKcLk`}FvHr3V$f&yJ7L`0OE zD5_PFU=K#J5rqiU9y&S`lcwW%=XuXL|9?*3mo!ZSj(s_|2Pbz7_w8S+YHL-ks%z_^ z?qC`B5V42_e2VXLfI5V|PfiT%fBo4p0I*utLu+L{wAhW4WyNw4-MqKr+v}@`aXbg8 zLl__INxC)-4u+D!g5xjY3*8c5nkB_#-a)4M>BO7~Cs|BmwC`}VNvWzq%lgJWkByq`w8;dT_ zcII<{SeD~M{h7{suvRqEw2`HxF_EQY8d-)Wb7!e=>g?Z3IFx592OOQh-%CUC4Pnu9e!`IV? zHFZ$dK^cQBn;y1vVz1@ys{8A&=G{=VxxbP_EQ<|!yGNdqrHNQ4LR~ui*vn#5i*;0M z%y;HIF?qmBx$e^JPn}(Frz82n<7Y;3V$UO6-Ck z`Rh}6%iu^JtLo_&5AEuI>!p1F;OObXC%?R>tV`Wc+A;d5eLIf0cx%eJKYm^+r3U6{oTe5J$idmy?N@HcLyYCzv&ylY2Q6|YUcC@ zS0JxL_+skfwaKZA*S29ZHe(YuVW_XC)#~eO>5Nu>`140Y|GY7ihq12!{s-FVb;8HC R$Nc~R002ovPDHLkV1iD+kv;$b literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/script_key.png b/base/resources.pk3dir/gfx/icon16/script_key.png new file mode 100644 index 0000000000000000000000000000000000000000..49bb24d71daee6956a5a1e4417ef1a0cec4a407d GIT binary patch literal 853 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 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/script_save.png b/base/resources.pk3dir/gfx/icon16/script_save.png new file mode 100644 index 0000000000000000000000000000000000000000..36216d8276dd679934346c30ace3006e1d76bbd1 GIT binary patch literal 804 zcmV+<1Ka$GP)W!a4mwm4 z9lAtNv=ALSSd<+NDwVaw^{3sLb!X=Ld%vD1v~3H{e06ITmmVL?oETThxJs&&OzJem zHtwUrCLZ83e4hiPx_{6!^k(M?jGkMpCU#xpD+L1R^b^O%J&(6Mk`UL>+ z=KDX%bR-j>Tz%V8|BxWMH@@Yq=Prq6jEhpgV{ iMhatptY3F`RQVr(hfH%Uc-uk%00008!PM!jse+otDvXRhleu>w{(hr=P& zTV2;rBMofZo=3rrs;YWAJqHeofOC+HNSe*6&}=qN@aeaKWm$(L&gF8enM?+{FRwu9 zoD1NBqmclHW{%@Tw}6Wqg+f989t^&~Me(EkfChX#56VZfjYtFPF_lU|uh;XF8H4TO zj!YM$blUKV1mw(6M2qNP2;H{su`-!X|7n%u=>+~>3AvaIiltqd9#DvgJ&1=10t0D6 z$;|KlP3c1Y-2fh17umvCJQ4=!_2+B&{P5)SL<2$#ZY7EM2$|!%^Ti9`3q;4qtws{i zDI^jJKbdhUAOoMo-`t-B@esjXtJQ*jzYmI{z|3qKZ(vLsG2zn?;Y5OJwYqN@My1o~ zTxy!Ox4y9nOZhb^2wGcN&dWOz9qA2Pi2L&&MfZ)$Tym*VCU=T$Q;z6Ze zJ$g#19)u*6U}?pjN9Q`P1faW_&ZrhEh`zTzI_Q+4udtc{7?20{`>0tzC%6 z<4$0NFD@aX1`EXFfryb1uLICn5nxWaVpGCkj6kwT4ni1iOhPYO8V+7ZA`uje zMd-SYjtzD?ftn&>m3S@d6_=&B-;Cz zF*bAv13UKN-Iq6*nUCUQI(Jw5*Xv9h7Nm56LZ>KDJd8b9y7n953x!Z9A}LY;0000< KMNUMnLSTZ#4=Y0e literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/server_chart.png b/base/resources.pk3dir/gfx/icon16/server_chart.png new file mode 100644 index 0000000000000000000000000000000000000000..1128d3f338c0cecbb91fcd9ac0f6e5ea4598218c GIT binary patch literal 673 zcmV;S0$%-zP)7AT2vWj$BZsrIMeOXfs&qO}(Cv2bXmF`i zn$P8OI5_+UtuCd4RFa4k1d)YdIKBkB+$xvL=D=8hn7|*seIk&jacljqDPt^wuF-W} z_`aVg3xOMp%SK(DsOv`m(}89d1k#uEK(uwQ`+>4B>iWM+_wG-2kn~EK%bH+uY1OEY zT&M{>ut&^^18tc|#7X^j1Yi9``uhQ%%^X6#daT6L4gVa$DOmh%oF>}(w1O79jptw1 zfT=8SaeOJ^j z9Ox;eQmLfwvo0bDP8ISYeP{_k1*6;T>n$70^-rg?Ku7#^t7EmtFLkvlsX#yA^ z0&)=vupq!uG(a51$y=z`>)VvJ8;!<#uh)A?qg~QVB`&`J&rxpz8Yd(B(?r6h*;wB` z0t*?eNzZxZ$!BFL^PX_?_pZu1u)YqRuyb8F${wa literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/server_compressed.png b/base/resources.pk3dir/gfx/icon16/server_compressed.png new file mode 100644 index 0000000000000000000000000000000000000000..bf49fad9deb97c5a6afb67867fef7151d3f3c19c GIT binary patch literal 721 zcmV;?0xtcDP)LAt_C)p(Rjrvjl$x6>nZFiinqh3jPb8dl5tM>LG_BlnP$G3zi&; zV5o>pV425P#d+3b(m@taAL7K|XcFnkO%?|tvRZ-)sX@IRk%cvG!bAN#(4 z+w(kwDyXXEx~{BG^7;I&kp%U6Jw|{>@pwER4j+L-AOr!FHc~h_8ArLidXsj464Yw7 z%MzSOBxWL!2sWGFAiD>FKp+Al65vGUIL>Gbba^$MPOFV=_uvuuef=#F1jBV{;fk^` zl0bS4g+j0_tKXS(oR~kQx{LkpGU&f5kj$Jw@{$~glwPmBp~@+sF2EQXjVQvVhUJwd z@&qQ6Y45bA7Z-~yrJ$dcP(+eoK6?h5wT5Wu8H@;>3l7IlVr%yz`(eed(eR4SF5JDx!-HU+!&0(x(aLNwrdd+;0^ zFE^53V$-K*oo?Iz&}?N_mL7g&hhJl%P*@#6V7`^Hd1#_@^v<%i-4wq8=5C=k00000NkvXXu0mjf DekwlT literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/server_connect.png b/base/resources.pk3dir/gfx/icon16/server_connect.png new file mode 100644 index 0000000000000000000000000000000000000000..49b269145afbb97ddd03fcfa844ea832c947fdd5 GIT binary patch literal 755 zcmVwYT0AgCL27sE1k% zB#Vk*Q+6?;e9+Vt!L4!K*`1ktXYNe*UVlWT^w7ZN+<|kx?>px^H{km|{^wKwm9Vg| zaNl*^8;;|sJc37gD5WAk3LK@NP$bk5Y$CIXlI%=4cd(q9B*cVPIfT zN-yMdJTl47IAHqHm0t=ttI8)@h=c;2s@8%}%bVy(RAhosz?g^LzLS!DUxmLngP`ow zrfn8+J7Zx$33yPOy6}EAf^^3q=H^}@`{F5>9HNI({R$?_cfm&~2_!((r0s!M>3g`lJ{4?wIwATQp;6yHt2^& zKYuq+Eb5L^v&R{AmzYgUE~OhIXUe@VXP)2T#eMsaNyJ@y*%#F`%&V0x=ZR~P^R7jY l<)&}aKbCWipX^bu^(V1WxGAiK0S5p8002ovPDHLkV1nEbSAPHi literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/server_database.png b/base/resources.pk3dir/gfx/icon16/server_database.png new file mode 100644 index 0000000000000000000000000000000000000000..b24e826c70485ac1eca79266cc94b2e1ae0a1d90 GIT binary patch literal 666 zcmV;L0%iS)P)#!|MU57FB*-;`{iB zltEd-G)>MQ3WdU}jeu6Gb%zSx#^dpVu7@$FB3Kqg8!6n{isS6;^d+tS1T>q?r(B#! zB(@`w2rhs2z}+p&hGkm>vY`kzpU*dsK$}lfsgx|PuCB45;;*d>0$A&Ka`;Tf*a+Ym z1Azd>7o`0^ zD1W4UA_^R@YymM~XLnz^iwE`sMl_6kK96WLn(%l$m`3tlgU8W^|fpsnH5pPhXPm^s~h7O^zPdU%%v&b^m;uEheP!HeNbn)AFSBJ z=D4?!CCl+yPJVsw4MJL2IzGU?Fbo61kWM#H6OdXN>u%=Xt80A&C>DzcolfU@rBb;#Kd(U#Xvm}= zAeGuiI(eV%75S`kHk-lk_ahVv34q7fZokG-sdPy6V~Sn(F=ew^z>%07*qoM6N<$f?lLE AtN;K2 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/server_delete.png b/base/resources.pk3dir/gfx/icon16/server_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..61e740fe18dc615016c3493811f305df96d678a7 GIT binary patch literal 668 zcmV;N0%QG&P)ZQIL=Mmwl(g-y|iYtDg0bIogV2(V47x-17<>@P+Hf!VQ~;Bh1ADY_Vk1>Kc5@s ze}58`N~Nm;9En7Z`Tc&Zu9YFOQ_4UY-hbj=vgo8wo7>bZ?mX^6EGP}5o4qgAd zf>y7X3>E~5{sEcYRlyGFL6@t*C6FW{GilXc39MrFM;3HnTt|X7nCvx95Y4`y#>dJg ztfe`ee?5c6OCFj}YU|v_+9e2S?u!(X>8@nT&ql-J&^L3?zb)dzt-H{Tgi?Q*KmN9` zaDU;lXQ!<|OhHxER^9tl$hWZk7^g1YfN$j)lt&}z{_q67@vzDiHtH&PUMLjK8is*D zAOPQypQzOua-5=e?fX~wjvBzVJA2(9k3ywNui{G2X0t6|kiq1HIx$HB zW_et?e1)g6CxGQBiXw8kTq&|)pgDYkM<-j+S+T2y6lPy^62aYq&DA(8O6C>^FtR~K zY!hn=v!0MX(AnV8*}uTWDx7b$!|CsWCwLOS(jg>=dLNe^lxjuzW(EkiwDRc8MWrzT zziSEZ+H+X@`URpzLuJ)LxN8EQvV&~^htSAO%-@~E2>A%S!FH&NeGn@w_$DP$RJ5!j z=g*b_WwB8z8Ur}>1X^l!cp9%k$vlHq)M0nmV_#u3n7UScz@`dA}==j2R8?9RoCPqd^kk99_k&dImN83s2usHn$CKPP0)nR#b2G3^$ z2t~&h{yYa9(B0jAW^Qh-qrbm@GLw9X=C&R^WM%8FgJjux z8z1%@)9>H8E5K?%8h(ZObQ+(;He^)?YjH9bi#7cdaN|O?+&qJbow|jiS2#4N{$R0WLTZ2{0maUAKP;ba*kDOsb7Wqlp%QS1KhU;N7@5by=0s zmq6AS3WZRs)!NF8;Y8}BQWt;JWwZBmAek9~JUvF7O!F1lQ?STdk6+P4mt#iL@Kj(?SViZ@x(dovnP-+Hn95Y`kB52 zT`>FGIGz1~vGoN;+ytw=L1JPK%=PZAJe>~iAdt=J+(_9tH9m4-G(O@;Y8GggQGD_Y z!)611)4NJ>t;d0!g0AbTZfQU4Rk1%7f?;igyH%=>gVmQYa{i9yyY9o{Dh&#KClkq zZ^`-W=(`>n#l}|$Yi}RC(E2^+50BD61>-}qA41;3ZisG1`*xOo17YZXX4HXKtN;K2 M07*qoM6N<$g3c2*g#Z8m literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/server_go.png b/base/resources.pk3dir/gfx/icon16/server_go.png new file mode 100644 index 0000000000000000000000000000000000000000..540c8e2689b19cd661d3f07ec6d5c69a48ee79b7 GIT binary patch literal 706 zcmV;z0zLhSP)7<1w@I`*?5OI84*T|9oBhH}d)X zV_ny$7-LpT(?ounOeSx1Bq$b(0RlV<27^hr+Y6OI;2f4ea@pG(#Qc2bI;{>8 z6bgmQ0vry9qduPxrLScOb?OXyK&ctFdYopOnzzF=IxIzTH9TSNw zRv8@$M2+3u-KbWpO=ZKt@W_~@Zno4#v;XQqFdGCChs31_>&3!5%7&#b{zWFQc68tn zplmj4#^Z6+YBf55z<5&3{|y;v7;9uv%2$5X>rHda_}~n%R!c9`2Bty_PB{afo|wH(i1~} z&mbZJ35Q%B^!cO6Z!BTy%i>mD!&!%IJ)KTZ(mdRYL?UO7ODFJPbqWeO)2I~TMhXw( zyp+KE^<^xqJ^!icxKx=jKRWim##AbmAfj1{QTs88yd0gw>A`WlSX(G-+yZ}U&%wWZ o(p|@%!Cl@4H>AxOvt;l80V><8&-M2O*#H0l07*qoM6N<$f@GaWM*si- literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/server_key.png b/base/resources.pk3dir/gfx/icon16/server_key.png new file mode 100644 index 0000000000000000000000000000000000000000..ecd517425f0cf0a573f091656a0c69e294b6197f GIT binary patch literal 746 zcmVR5;6} zlS@n!Q51&%dDs?eX$!L{YO$aaAT^% z8wrtxVNvT!(-=&NwM9+Zn#dzTR2m+|($3p^r?x7Vm6P0@nLFqI&VSCGVRT)`|6Kge zjaV!eR1{@UmSvtqkZ3GPl4zXp`~BxC0uqUYod_N{91g$PTn&+kplLAt5tmM<1L1J! zEP47D5Rb=CQn4Ti`>a+g<`U7ws?&F_ zfzvp|MzQqNH!H3#j~%}BVf-%##aZb_G6l4GJB;cj7tG=`j&}>Nw_Z7xnHjztyK`i@ z<3{><*+B_lKuBdOqW7yc^Z1f_jE;l*VQ=n3ZZU*Cw&q%gTbv4AZ5(1tfU;QqJva(_ zn7WS!r2xBk0P6N9ScH1;)qty~y}GH@J!&|h!zq1{)G}>Brx3Dtt?nj-%`oKk1+ZKO z44Z?gCIb|<@nc2g$}P}S;5e?>w@Rn3!6Yu>fc6sRS^`$SgVipF07*qoM6N<$f~LGuF8}}l literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/server_lightning.png b/base/resources.pk3dir/gfx/icon16/server_lightning.png new file mode 100644 index 0000000000000000000000000000000000000000..b0f4e46cdfab24395e96c434d7e4f81f666f93e8 GIT binary patch literal 729 zcmV;~0w(>5P)WDY2I?wA+J)g@swh z*tq9;Az~0KxUTE-L+yVFGMP*>3GNw&aV-*w!yyrbfO<`uM8d%Q{PVvFikbca$;C7w zD0sNBg*UbZv_J@}9F7}CA$k)Y3U9HIWm#<@P#1rB)IBUb)@c`W zV~ft{yH{`1uq+F@t|JpA}c-%zc%xMO9#00000 LNkvXXu0mjfaz;V& literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/server_link.png b/base/resources.pk3dir/gfx/icon16/server_link.png new file mode 100644 index 0000000000000000000000000000000000000000..e8821dfd88a4a178df1581e12832925c401a78c5 GIT binary patch literal 706 zcmV;z0zLhSP)?mgenukSf$Ow%;{&(Qz*V`F0@b#ij@ zxZm&VX$7rf9v>g``Z^Q}JsL?+C={#&cxkiQLb7}jJpw^hA^ed`yWNI#dL>L>e-q^M z`Fjj@I2>0@CKGnPR>A73szKFMBGRA`S+Ca{9f68h+-|q{(d{0gPvFmm91*Ce^UmFA z5o06)XEYcLXt&z~WkrF1>Y7m3eyMY_&vn4e3W2zY4~4B4@}Fo`ggWoJX72yn!Jt=~ zC}x7Gz;&TMbfKNo1KrTUkU)^IvNFituckW41Kdc8hGB^|5P zDhq;WG2$IrNz43AeK;CB`x^az|5dNo zn+^tpmuW~wqY?Fb9i>u9WcPSHn3$O0UhR>XE|bZ8|Bb-s^GTFBK#I#m;3Sa5N8M~T opRypm6;{4LkrnDigB(5h2_j2`gUi>R_y7O^07*qoM6N<$f)SrU?*IS* literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/server_uncompressed.png b/base/resources.pk3dir/gfx/icon16/server_uncompressed.png new file mode 100644 index 0000000000000000000000000000000000000000..86e8325b9cf7938320d26317b1a59ddc23cd6892 GIT binary patch literal 669 zcmV;O0%HA%P)o zmTnjo#N%;{$781#wOUO^qtRcCC%e)iaFWe6kO?$RK-YEn{eE>9SivT7xryr@aC7Y2 z$c~ladYiP^Pq3RR&C`<0Ux?tE>+nwIoYzoN(EPEW%eEu*a|dK@V-c z5D36?QKuUy998{(pX_K5LZ~&x3q&AivzY>DnM@|$Y&IVki^Y@U<9E>A0yl45$Ngjq zpX#4+cGkw}={MBtb^M^=^?Kiu3X_y63F7=~%;)ndI($L%zDLhi_oR#=SOyS-!hh=FNvz5*&gc}4bkUS$- zpueTJs?jS>W4VH5cvDBnk}bYn&!Q$gHPEkM{Aeg6CFgw8)S-s+lpfn7J^^Wlx#}xw U_BgG30kodM)78&qol`;+07=(QkN^Mx literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/shape_align_bottom.png b/base/resources.pk3dir/gfx/icon16/shape_align_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..55d2694008bf2e0f60ce19ee9a2bbd8a786a2b81 GIT binary patch literal 398 zcmV;90df9`P)DFExf{Zw)P^3DA)+Tx7p16zeV2eBJN`sG!O!r z%r{>qq_fRm#^J65xA(7`3Wk)qxjOIm1^`@~9w8eEp5GTgVh8&GR>?|J)7!6b_t4vb z5)9aIeRjRw+BgJn%>h#W0y-C@uGM%f6pBvD)Skg0XTAk-QuyBUn< zN;P$?E+2m3@;x^jxVzMBC#}&PhY07*qoM6N<$g6GqtMgRZ+ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/shape_align_center.png b/base/resources.pk3dir/gfx/icon16/shape_align_center.png new file mode 100644 index 0000000000000000000000000000000000000000..efe9a98e5fa3c6ad11072c7d5383c10d7e4bd988 GIT binary patch literal 384 zcmV-`0e}99P)Z6yAF1om>|ST ztKHFR-u%C_TS&rR#$xWUuInG^#ZbZh<7OKK0Sbr!oPg)`=K8c40#>`ki?apTCliRg zlEUj-Ocaa&0ziHzlBp`G6i@TVfL<<@Bqx|guvvfy(7bc&my!0N1m(V4lyq=bRi(Le zNvR9#hi1|)cfp-7Ct3?wOSDEz&|1=(k-c%ksD` e{M&ClW_$rjx>)p&(flj`0000i08P^j52wc?^pz~| z{+5E5H{Y(Hu4@1Skd}#3sVYT@{hJmRi$#&$%TyG}1r}?t9|7htd)Lsfy!ajkDt-Z6 zU91o2&s&(!=K$Q?&o&L4`Lx!Vx>#S23&w$uyhfU-d$K`9~Nd8w!zv$M9@Z1$jp29TFj3j_=8Fw z3{%YI%$@t@b+*~1_I?xG+&ypHkT%yBC*7X`0H;U$*kGH-*D~zj_WsiblwiPy%d>+H zKsFLsCaZ=4DL6hHA;5x{_a@9VN{~#-l-L5WA>DQvR=Nn0X;LB+>N1A`ku;k2zxK4npfSnM_=ZsUd2J2vMpSkH_8s%x1H0<)AI26!ZDKD6N!6J>@l|AVmlDp4k6{s%-F`BPf$oC&{AN@ zdiEsm`7?=OX84O0rxL5G3YAyiA3W{4u_Yt`k_-{ROY9Tg-K@O0-jDvtW z{2*|9y*9tOg^9q!_Q>;57`(LL1f6BD4#7DRBzU~PGId=~JGk7O1tj^fbWx*#*Ac{h z0ba=a=eWF?0CQRvsw;s58J%Ft^?dlC`7PvXK46MN^%$di5+|bh4y+|Oy!L_^s_LB1 v#`bl7E&d^!7k=P_NG200000NkvXXu0mjf?~}0h literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/shape_align_top.png b/base/resources.pk3dir/gfx/icon16/shape_align_top.png new file mode 100644 index 0000000000000000000000000000000000000000..1181b43fb258e3e524f8b297c4d301bc51e1fafb GIT binary patch literal 406 zcmV;H0crk;P)iXZHXLga@5kw1` zhA#fE*Hzt}ZT=Fw0JGW5r4;(UXSrOmSS&VH-}kG0DTVob-T`#~LI7}cx3B>v7_i~u zbicd4eO^~Eq|DX%akpWRf}?{S1X%F$u9fcOa1Yr?@c6piPGCd2?K0H0ekE3#NN+c& z3DVjib38X$K{A;l%7lRi0_i(Jt)iw-nkrGE{!GvejIudIh+13qOivS3wMNQr1j7|R z!z+qRQ^v%`6jG$Rbq_omBvC~U6cJMdhNrhAhlz~uD@szMRj)D;69kuM2i>-pR>H(k zU20R=YA_WM*~Hm;Bk6Yr_0!xxd~68E`15D_0t@>jBdvxMApigX07*qoM6N<$g1oz_ AhyVZp literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/shape_flip_horizontal.png b/base/resources.pk3dir/gfx/icon16/shape_flip_horizontal.png new file mode 100644 index 0000000000000000000000000000000000000000..8667c81f8b2ae38922a801bf8ad50ae8cfa7e7fb GIT binary patch literal 403 zcmV;E0c`$>P)+Q9Q4|H>Gx;$-G!ZQV78ZfoO&~77*3Nn$jc&kZKoCTmAc8K!LP4<=!NN2tOlc{Z zN$xqL$HGYbLH113OaYT)W33X5N`C}SuCsO{M4d)0!W1Bd zPzF|)%AK8~r}nqN@l_U#p4Mv-asy1$8wsx&u~-Jolx`n9hA#o5C(U{(u9g9#gDRe2 z!e}g*5zR(5HY)i99A1uEM(-{!M3@w(Q`3nM*_asR0^}go-P*tZD6~=(l~M=~!wKks x1gKbXqcC{MAPSU2?m_Ytz$O4h|MV~XCU1V{%3*(8NnQXpYiVPVoA5~c|!VPFV?AVO1l*q#wuVDF}{5Y`EMTa_P#5+JM* z7NrLtc5{G@^7nWG`CDHlY@FTuu<8=_lZ5psk-QoqP`Hx{VV$sN)+C(P0F{PBnQyZy zv3A)TEIq7N~!NGFz151St77tx49JDc?6PU}s zU^eqSJON>auuj<9wLVdFzOaAY#g6%o^o5I=?bdiJ&{?IkkvMg+S?VBl{)W}#Hm1{! za5rFVjj=`i=oRt2z*MRp{)mjN&{-$!O(tv6TOh1XtXGZyt1-&_0(6x6mpf9k1poj5 M07*qoM6N<$f}NJIe*gdg literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/shape_group.png b/base/resources.pk3dir/gfx/icon16/shape_group.png new file mode 100644 index 0000000000000000000000000000000000000000..bb2ff516d35dc9a92ed6ffdc79595d61513e65e3 GIT binary patch literal 553 zcmV+^0@nSBP)+TVU5_x7IrE&y4G<6LW)%R0m7z{{Dic2rZN9Q$X1&!1i?xJlHEd! zMb<)AaLd@37v7sQ$Kt*h-|9m$FwES`%*UCz+-Nu)o=e)5bUGLe9$*XW_xtbCG~Fk8 zS^==z>2yHy9=5bNj`w@L9^yE@UnO}mnM@vCy?#47TC5}hP9TpCzy*-N^X9b(0M_gE z+tFzB%*@_Lk^lflio(4eCs(C^W#d$;S65tM)myfdnARS}?B&nAG1Y9f~bPvTYI2|OiyFW_ORR02sPxSI|DVlF2 z(;aRKd!WOt1W+_H!3vT$JIHb~{vVJggjsddXjHaLhZC0-bi3U}k|cX1kEhe=697of zarXTeQU_=bBVa~2!_$6z^8&YCf03D;q1|q4Hk+y0Y)TTg@kXPe@p!CSt){5eY8@v@ r@|fhwd_LdX<~P>s_0MMZkmR@D2_>Rn5)Y(r00000NkvXXu0mjf$qDH! literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/shape_handles.png b/base/resources.pk3dir/gfx/icon16/shape_handles.png new file mode 100644 index 0000000000000000000000000000000000000000..ce27fe3a0345e03e919b54ca3b6a8498743b2ee9 GIT binary patch literal 538 zcmV+#0_FXQP)Tm(Vb6n04%0-0d~Z?N5N>2x}bMx$D(zp$faLbcIm6))=iDcNsK{XO_NUIz9_#=Hl90fplE_S$iRDekpz|Us6%gcl z10>7>u(;bXN$%}9L;!i)H44lO83AA=upo5q1c5U!FDx|env1*bl?cq~cLH;UH^p~Rgca1Ok;(*H5ZUXcXOPFe6C@8ghq04j{~AV5iYe^SBjqm*l4!TaGj6|yQS zl0>W3O7lFgJbe6&SDlNa#1ExQ;_~7(-;>XH?~^Rc>h}P$EUWbUeQtj&SzNDKTyL1C zYZj|t%+odV)rMrXCP_Cezg;mNk8#e`cJr5LHk)4>jfPdL)hmSs`qPQy_Y4;U;qFB literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/shape_move_back.png b/base/resources.pk3dir/gfx/icon16/shape_move_back.png new file mode 100644 index 0000000000000000000000000000000000000000..a216ffd36c85ef8502b8d3e5255994d19c1b4837 GIT binary patch literal 395 zcmV;60d)R}P)v z+whYUbTtD=;_3AxvLR>j@_3VuCP*of(#dy15?2>z*unc(K3-w5STtU}9or^nBL$nP zxpFy~Ob*vRzkSE`)Q^SnzOP?8cAX z*{yXuWVu|%K5qiHBIoijdLMx`0Gq8@eE#4JzB}(FuvGu=x~*2L7>~yXKwBe&!GPIp pM$x6Pz5*+|0DT4aFQAXWegS3uME2I#<|+UH002ovPDHLkV1fcsq%;5k literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/shape_move_backwards.png b/base/resources.pk3dir/gfx/icon16/shape_move_backwards.png new file mode 100644 index 0000000000000000000000000000000000000000..ee3f9b27ac50d9fb560d7f136c2fd1453150ced1 GIT binary patch literal 358 zcmV-s0h#`ZP)@HXh(hEF306Q6`_2r7V>{$iQE;V^UUSdf-&-W% zFVXPFSOUDheNAO3Ap!*~BL^v1P$gcT9~Tz@fQS1#lHfobY>>=6C zi9qrIaOiv80Eju^%ymq*LRD@6%9O6VT0sWebQSjdeQaZ!^?JQn0#tc+J9C}h2K8dK zdLjwi?RKu9YJgmG9ow-(2_(@p4Yp@M*9&QR)zvye66AS^l4d|(=KbTFI`%&d)zki! z5Ssww<&G7Qj|*2z{Lom8f6?>>PIkVv)K%QjRejY(R}`*(6?jp z+G0hH3!I310<6fv$?bSN`g*+{AesWUTCLdc_mtNN%K=-W6PTYtZaH8HvZa6i6&L{P dpY=4B#2-g@ai@NbQ3?P6002ovPDHLkV1iK7x%~hD literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/shape_rotate_anticlockwise.png b/base/resources.pk3dir/gfx/icon16/shape_rotate_anticlockwise.png new file mode 100644 index 0000000000000000000000000000000000000000..07a30206c2d913e9de72e7befe0ff34b975a5c6f GIT binary patch literal 657 zcmV;C0&e|@P)rBSW%1yym%3h>P=CJq=%jqJXyqou@YzvD3*eP)k}mbY7q~i z;GrTBD_SU06%3(@S_Ny;^o!gT-@Q5A7Ab}S?LJP1C4Qi#inM2z{qs&8>j3owfJ*pv4@YF`X*Nd zoPBZf^2Q4Pg&j3PkhTPa8BqA~9rA@d43Bk^1zzLD(JL6%Cs6^Vii=lQt}>0Fzr#L1)~3>`~-s=Ycgt!=LtG$^Cf#hW&f@ZE-58uB`z^`Jq1m z(fhf8v{eiNr8U#A8ZkNcsx5s5ONOVt&(3isK%k_Mhruzis7O~P+0iqmPT%^XoO#b6 zOQHe`WByjjgGg64w64+}E+hEwe^(H;6?}e>W|z8COkcK<&fLwQaWd|~nPJHi0Fz;- zkLbQC(k`U>c<-eZS`y$G=c_6Ua&CjgY$$qwe#}9tJp{JalHgjMJh|C#CU5l328sX; z&pT%vb`+SHj5{p=05G9&4Z!Up;H@Oij^VL_IC!nsxQcn#H7qxd13foA`)fy(J>Q)U rY-kFh_WZag1nU^vj$tRrYOnK8uN+@bVu@BX00000NkvXXu0mjfmTxVW literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/shape_rotate_clockwise.png b/base/resources.pk3dir/gfx/icon16/shape_rotate_clockwise.png new file mode 100644 index 0000000000000000000000000000000000000000..b99db7d7017d397c88d3f365d4151c2a2f1cf396 GIT binary patch literal 673 zcmV;S0$%-zP)-MvO4zAah)y8AdgNT;8aNt0Z#``ZBWS5ruW_!~&_5y@A&Mem(ZTgN^o`}~SszU$^ z7RHvh1xFm@)^ph0*nGGCHC}q|R4n_)A1L3n9&>Brm1ReutcF$^i>p}}-y)rv!{S1A zVD9e6YXDL=pXA)%0TJb?rt->iD68*Gzt-&OgQ02V4o<0CmgJKqX#oHth8qSBmxWt82N#=*8fj=+HCx7f zRfTi=WOc-~l=q1x#t%h^h5>6i)zSai1%ODQad<{ISdvuCby_M8I4B7NffW$v^VTwa z!ysl<#Y!62w*3Tvp2*`_<64r0B}rDtLT-7f149B603-l$UI7t7nGgz!h&XxaPUca> zlFVC@M$5qJHo=m>QhqYAV5c9J7%STfOuTb1F0-VZ{jT#**V$+0nYH{Q00000NkvXX Hu0mjfq@H!pQI5+Ti_L0YJ|=5)wx zkF=1qGlSNkDr^3|$ws8mau%VAs!N}G7ur`j3{a)&lwiJCaRceu$939gbwXgD!G7W+ z`tnW&{YVf#zprcNBv=w4wLNbW#_u=%`)~XMSM_D9ZJ#Vp00000NkvXXu0mjfl(La4 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/shape_square_add.png b/base/resources.pk3dir/gfx/icon16/shape_square_add.png new file mode 100644 index 0000000000000000000000000000000000000000..31edfce597565363903c26264756f3c81ec47a9b GIT binary patch literal 539 zcmV+$0_6RPP) zY*Mj<2s&tEg;ElO(UR|;EE2 zmXINo=@2a3IhPCp07@s1V2lL@EF*&lAQF82)gDa{Hg;|h*v8J&*;~c&MS43 zq~ic-3K8n{ABI4)^_J$J_x#;!&}#2->rws5>!%xweLw^e6Zxy>MrU8S(^#cAS)+38 zI#Z{ndAGSj?bFsmxmr3==qE4{Mkz!%`;`!Bn5~@^u3VfY3c>8z3XyauU!DWF-v@*V znN-fTh{%%cwzfH(9OL$-2LL?0`GO0lX8?)=Zy-K@Z}&P&!eIpL{%){YUuUDf#(d=^ zOKEE2mXIOT z>O*kn@_5z<062PJ1Y;~PU>OFh(i2W?ykPpuRrXGu zX8S{(Pp=p6E}q@9Rq8r05k?6j+`3AL6lUMMN1Qx!kkz9_x58Sax;000000NkvXXu0mjf^cC)W literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/shape_square_edit.png b/base/resources.pk3dir/gfx/icon16/shape_square_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..d28dc6b1a4420e67d2ad201e77fa6ffdff47b0f0 GIT binary patch literal 660 zcmV;F0&D$=P)-HHgciWXH=58>$m+)aUP_=fNurq~c9Jfr+{g4OA6VysNJCVr!>1 zyO(ukr-@eVVQOd_eeEr`d;&*7#Zd36d)>ub=%lXvJGs$=On&Pn97vP9zKEPnrBRKfD#EKdHd|_ZeufOm#a)m@NAF&m3;5bVE$Q(zLZS1JKPk-x02D-XgTe_RX z#5m7GmzbE!!E}bj^$Yyl#_Q*HW-gz-5F#kVUOZxW=<7_hAg}KDjh>#B%CwB&uQ)_iwz;@6pmo1X^%*Tz443SFZSDVxCn0000%A_P)#@-A##Iv1?0U0EvQG&ENA(xNS^k7Z^%HE|M4B}V92E{q3W6e{k)ec8 z;2o4;WI_>0-Os((YH*HbdS-6e>@`^r&%5C**ybRog9Dz3o3;H0(ZZPh3fB%jAn_JaCWIV75Lro?O_~d_!D*f|Tp6e0*C-kV z?*}L-D{Vv4e9~_iEKhKBV4Q*Qj-I$i$ODAHzoJZtqFWmbg;x}hm55tU8M-vhNLWB> z=Kx~N%IW-$qTG7H;Mh%QEVKA%j-FDTzWNfw$x5CMzKw$_Lx%n3aYJO)wwz~idx_3>Z)??@^wP9b!U%(SY5BN zy8egc`%5Y#=Q&dRfx}NIBrMHW0ii~f{+89x%o+fGChT%8I(hy(~5wOC)KNbJH(T^wDQj z6eh>aF;li@IYJTxb2IaN*tt&{lQ9Mn%+#O1(s+QB5)=tBa;k8a`Pr*9lQy3_ce(j& zZ))Z7-_`(NhS@}R>kt*Vv+xjeVKRhMYix0G?mDf|;ZyZ(T&)ioIHtj~B{3mdwn-W?A1_W9{4O zPKYe#dY|dhi;9~DH(x(?k0bVL9Kv zQoJ?!=IiU9LENsDeFNaYfYOs(+jL~IBP;zb`)2R_KV%7xht?ds^8f$<07*qoM6N<$ Ef_nG=SpWb4 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/shape_square_key.png b/base/resources.pk3dir/gfx/icon16/shape_square_key.png new file mode 100644 index 0000000000000000000000000000000000000000..c34b982a07774e25177206a5910f20507747cf63 GIT binary patch literal 607 zcmV-l0-*hgP)aH&8>vW#0l<-cT^NQb7+`9sfwh^a!rV%AD}k6{<_Z+d3^PaL zj8qL(L;P)85D5`6L)8^-YV9=fMYkH5XqafAs+i&m)KMwv@-q(Y`bjJp1nzfkAy7~; zMAXr=w2G1}O>#QD%8AS!GRMB~b+muDgFpjCT#qf1P$xHXoJ&p9GjJL2M~*~q3QMhJ za}SQ+Z5jjth-kC_c9TBx^q#tkRP*fKpQI*B93C3%4!qKM%RmH?xSP7W-NIFtgFgJy z0?}BJNYtY%QG{BRjpcf*jld9b#cuiuzrdN;1lmY+-oB+ zH-qr@WPOVM;2i^(hOowaBC^iR+ZyIoF@=S>%FU6N^Vv26rLb6agM*6)KXLL(hDLFm zc)W+1k3O%Lu2bA|9s^!HKbsBr?;gy*XK`})bA4shyuvk`etcp5$*uIrc6sst{jy*4 t#SfM8)Y0m1@6YV)>ciVlzfWwJ_ZRVAlCjH(sapU5002ovPDHLkV1kNh85aNm literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/shape_square_link.png b/base/resources.pk3dir/gfx/icon16/shape_square_link.png new file mode 100644 index 0000000000000000000000000000000000000000..b885fcc60638e4643d7da2613fd79090aae536d9 GIT binary patch literal 642 zcmV-|0)737P)VHAd+Ld!L2q^VM98w(n1h)wF~45O2p7^VJ*E>2zbFL1)dQ4LX7H*KPh4wz^h zOo>C|P#S_Q?WOh#F>;Z@{myadEwm{cXL^V8K6&4h?+d6ZN0}jxIKi%X^1JcDFsi8f1_4z?)lcJtL=+Ll z>>X0Um`+4g5%G;(E&Y%^BZB}n(pgjx5mfLEvTy7HJ?{{JCm==S^Y}gB;H{F&jVwG-FBPJ>Jp*t72@M3SzY_ZvD7TX)+lb}9j8yl*!ky> z&#yi#l}gVJ0LHMl3(Mc$lO9)Y+`EJ8x}05G@Y&^`V~e(L2TQmShOBjtJPSb z`;;HNT+zVhcLKkQ_Y#Fd;ZIKjW#i`$ z&c(w3oVj?5<LHjPH3 c<+|?G|E;ujN0TKn=Kufz07*qoM6N<$g8H^2*Z=?k literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/shape_ungroup.png b/base/resources.pk3dir/gfx/icon16/shape_ungroup.png new file mode 100644 index 0000000000000000000000000000000000000000..3a6f369a5048b92bb2f625afecd70f29b32e2233 GIT binary patch literal 666 zcmV;L0%iS)P)4!9)$b<|9tNU+CsbaPrm=%-T&Tq-}~;JVp$fPW~sF0aycD| zJcw2*l?qHIrPJw`rfFUgLbUSveBc-XE>9#9fqK2}f3{*+f&-8)iUMP|+l5#x29-+1 zf1(1;d9zllU2@DV!Q!k<7FoCnWT6h{&Ru{~sRWF%*OLUw$b+Zv4C}1RCJV$7$a^H) z-4}4{>a2320$QWQH_waE`LzS;j2kXry9@Ri*Wio`nHLU+SJ00jVztp|glr=M*)Jxx z_jHIxqwxFZ4y$v9D0AR)a@B&ERc^k`Fu>UNgpz&%tPgLLt51?|a;f8r-<|NEVV3@`Ixv zk00KIFB@-Z_*$qqV4EBaeCWw$v*^bs__%Gr2mK$yfQ_$zp|xee=k*4Z%VnBM|8Rh; zG5CDGRj=18G)-$vo)J`4eW54{$$mxm%4vV+{~xG}o%M|tZ2$lO07*qoM6N<$f@ZNP Aj{pDw literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/shield.png b/base/resources.pk3dir/gfx/icon16/shield.png new file mode 100644 index 0000000000000000000000000000000000000000..3cb4e257893adf230db7220c06fb9371360312e7 GIT binary patch literal 702 zcmV;v0zv(WP)CSS=grr57X34Zl(zd#$wMb&<%>`t-B(tkBb(psfna0f6_}Do~^xke$ZPQvRr946H zWWosxshhe2GGhTlX^H4l2T{)>lHM28PjBPv)052H^wfm_GUcM~_VUEV$3cdCKWX1R z!rT&^3rTv;k{#1R&D<>@Px1a?%-hNzH)w3T)o)siWm4p$YE@#8C&=cg43(z=rJn}gKmtpUPjP_< zhQXyc#h?f*t`d2Vd9yzWR3(s7PzH#A7!f0%A|E3em_y#OBXS^bn8gJ3v%wOOhaiEV zN+Bg6K!%U|v5J*O8kij|KR-n{eladP2^TtCnBu~OphnPUSs(4yA3V7-gl0O@~?V*x@CTl&E<2=tI5q@L#DQla@S41 zJh{xk+x)uL-5)Og@e9A})romiTU+;hxI5}I{Y{<6W=--* k<)9^%y{&t@hew?Fzp3k#2;Op=9! zVS%RGgcvtB?=hrnT(^1LdEEQ||L^Y{iyPBKvvKOIPJPa&)A<@z<$uZ3-6v zc~$Gk^h9y;%5Y0+$*))mIb#7qgC5d9!ldIb@VnnpFu9T5$YrK&jTjd|MT^t1mgM-l zi=cwqeuBO>+~TDe5+v>*=`WxH zDB^YD#jY{*;V7u!b$6g5&jH-u$57F%uJu6zFoLAQn4AE$>1<~_P>T~PCNq?*1bT)6 zRzMZRM{R&{ERX^dVAKOmgLqjZYY{8*w}EC2R0Gf)APsmZ9%=*BdZ-GBL9K*F0<0k7 z;S|ik4n)A@g5!gewRjZEqxJiE`ktM{PYJ1^!X4M4$r(0~Gs!nsaL3hQLK85q!MFj& z^?C5w(w-@!VR-|4w(O;LaWzcjP~E<&Q-1(e8=fB+?7UC%eKWb`8*vK8;N%7vcaYn! zlPsKDi*+oum8-EPpl(4uz}^wBtX9efI_@#hai37>HjFzH;|vn-OAs<+SwC+-00&oH zV8)~xfcz1FsheLVGO1*BZ?u`-$W^RA1x2fB&I!kl=p3xE?XyZ9830Hn>o()jVx z+;X+D-*LwrDVp8Lxw|)dqa{Tp^)<_wRk4Towq)Bpeg literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/shield_delete.png b/base/resources.pk3dir/gfx/icon16/shield_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..22823a70d9d595c91898132ae06b38d956cd75b8 GIT binary patch literal 768 zcmV+b1ONPqP)_wWDzWofpWZjRwL)Vd8iHwR;&_<&#(aXJ|2rC=4&(@vrY3M%S$@!-jW z=* ztyLco*Wo15n0#0=A?aRByJb2o>G^@3N0CJP%2&wrwamVeY0834$+YqI(Vv}@#Oext*GL@6XYIDnd zAA<~q7WqGC@#Xt*&Xd)?q_FV-8}>d63ap%a4-57fJrO-yE8n*)Uk4fa%1QE-Q&{pR z$N*vK66xX>v@g5`GSbyc$m}P2Jbf|&hC&9GgEOo%g^P0(5)=~DO+kUEP^Q~%?f@E| zJ_Q2_EJGp3MFHr5%W+CU30MjU3jqse^mzJY0vQS!QVxoN1V|An3ONcXl7TrCtU!;a zPr)!tiAsA2Yct?BK$Jn$0hd!dSEGJ*p7v4&H|UYV*vK(n_w>o^{pN3HVEj6TFYk3Y$#xl^Q_CE7r%8FT(3 z3r-UM^~Wc7-lAYHMt;+qH;q)78y|02t5m*iYd7}MJgs_{E6Z`n6TR&u@qf;Lxclai ybx&BVbsWd>_wU(r)Ga$pr#Q!2ut=L3{<%oAf+b{E;+-G}C0%qCSQkM=7lG`eZo2X^ z4eBCEy@)7AgN%7FT@r(le`@L`$DC`&?HtdZ=lA@6-%sb_Tu6{Ny)Onwlls1`t zw)FcKN4tlPVEJu=d0u<&4Wf)_5kpiLXL-K=B^rL2w`R^wXUCEiDQ$fRCf=R>X2((2 z(M5UlL9%d~DC5@O*C{Lzte}VmOL?8`PrgE>k|5 z#7u>;Yon7s@IrM&xs$}d{c+;i4T|Ww|s z5qVmiB>u~lC#5QQ<|d}62BjvZR2H60wE-$x;pyTSqH#X?$9aZk9xk4=gcS_} z%w2~hdwA07|NZ~@|FQilArsd8f6XF{Qw<&ke0ci5`VUv#|NpJ=2j%aCIn+%2WcF59 z%>CW#*}oUPcm3UcP5krW-G`*(r!XhJ>z-n_f{E?eO??G7rnQMK8>51>n=~5O_yZ)GQ;#)>*f=EeOp`n$p2lMq5y8c< Y)sUsE^zP|RKsPgZy85}Sb4q9e02 zk}*reKp2Lbf0AEO7ypA}amXNqYyp>Y;Fci-g4`}4WOLWH+9@cGQs}0F*iEjOG*W}4 zm%wK(ZQw2m_=MnyjyI)bdn5JojW9_ApWwoHWG)HAlBv>up3c{Bd7V)Nj z@iR8U_45rBpRWSDU5?-*Tkw3&gP5hEC2ui07*qoM6N<$f(bUU AHUIzs literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/sound.png b/base/resources.pk3dir/gfx/icon16/sound.png new file mode 100644 index 0000000000000000000000000000000000000000..6056d234a9818d248987389d4a621e5c83ce0851 GIT binary patch literal 610 zcmV-o0-gPdP)FDRfPcVFW5d%9V=z{?A#;oriL5xO+n6O2X~nf!lQuE^VWXpgu83qI(qCF{ zS}dqc=wWy-JjhR6YYDxINHb)T^nMSh)vA20R`F7)lzCSCZF94My}d73T>N+m zpyXWPL`#FF;s+j3t(LL2R!6+EP98p9G9EaJe<5S)o@#CPu0JyV*YBbiNC<>y{C`3_2 zFc^fUC0P=`0GC2D0rmxry!i<{eh#|t2UjSV*w|QyY37m5W)KQZKoA6m%^;bK|K7sb zq~^Y!1U(%y>Cs5W^^bz?JUQeR7IK)M&$43OYdMwDJVcVBtSjl_Ar8Hmr2)a$eK-tv zNC4d)(7D`Piq~gVUR7m2k$BH5O6=$i%I6Kpa_sVNy!&j)9UKPT@*VWNNNm+UIUciF wPJ00!a`S;oH}3WS@hUTDnx*^y9@F3E2OYGed{u8eJ^%m!07*qoM6N<$f+a~A3jhEB literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/sound_add.png b/base/resources.pk3dir/gfx/icon16/sound_add.png new file mode 100644 index 0000000000000000000000000000000000000000..965c503c6088f5ca20ae624ae9f9bb8f05490640 GIT binary patch literal 684 zcmV;d0#p5oP){@e)R=6tn`E0`O&UochFZ7FhGdgX0zI@b zfwou(BBezH*PQIpi)fL8z0AQtp}BZyynUTrZBg2SA`X0cGmm+n_nl#e0l@r=nEwVS z77H#}mcINopj0Xj&|*nZiK$9T94|fX&Uf=yW>Jbseo%3z8&JU=68c{18C+IKL-EK<@goWW*KkIou$FceWXN zR;;c*gQ6&qWf}Q=9;sA{&gT$|i6&ro%)LY0f_2wLyAC_e9ASq+u3Etu7u9GiKoA6Y zyE;cmU`TyT?i+$k6Byz~!4D7Y4!Pa#<`cE+CuDAd!f}ZXbiiVxce( zLZQIn5o-DIjdXP!!OAG^KN}ku5B~vbQ06k30fR6Ek~oG3E?;|b;X&0ux5We z`<%net$Dof>d@Xy!l_+?|K8aSlbnjOk;yO{4)bg<=w}7Nw_|`ZnG|^5X97IRt^WGQ zD%L;MjWyJc0Id_k^~kCIkw-$i4)6h=OtpUi7|C71tF5Q_b!>c?HvlI;Q3{%%>KgMK z(KG#$?uVkAKq#+$Cp$P!bmN>uJ&&@^o1KkltZ82T<6lQN7pT4(wtvQgk^c_UnVcJ% Sc~{E-0000 zv4KjGLD@@SwqBY+AwKj_2x)Ps2A1Yat)lSTxi^%;0wX%`a$6Fye?p-;}9Oz@3_H4Is>e~!^?WT9P4(UVR_y$uYg2R z0LM90z};reLY114GXmmv;A$P-B^yEOFE%_9+Ev5395PjP4WPtcoxO#h*GhbsI?f-T zC;7Pu|AZ>;$? tsn=ZC^sk$??2gfnFO}FzBE_uKzXNI$nkY}mb87$q002ovPDHLkV1k=gKso>b literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/sound_low.png b/base/resources.pk3dir/gfx/icon16/sound_low.png new file mode 100644 index 0000000000000000000000000000000000000000..4d918633fb7c50bb382f91385540919583695bff GIT binary patch literal 524 zcmV+n0`vWeP)}W-Vhw;NT#RL?T9uLxYyXVPSxHJZ{>R$9RZyOF=SYo-}k2-w!jPV1Nk(IL7DO zV|bqJ_Mv1_1jn)OuW@=|^wWn#R~_NJtU~kr5%BG&OrdR>hyVLb-^~lVI0N<*QWk}{)T2Jp~1;rnJ&N2haulNhlC*Od9Gf>KFEtyV>~T1KT( zMys`lcDs%9Y!**GpCvG7uAr)U^!sP%^?K-byD$s`r=o}<$KlrRw*+%D1$0-K<~|ff zfh@~77KHKSyI>I8i8yRaw2IR8ItU>!0|7iT3@*K1Y{mtMqF^t`<+5lr>Nw*0@#HI( zfyeDeD71=LjJFr0(_1)Hq)$07*qoM6N<$f*zgBZU6uP literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/sound_none.png b/base/resources.pk3dir/gfx/icon16/sound_none.png new file mode 100644 index 0000000000000000000000000000000000000000..b497ebd54abd420d6ad527e45cf61be55170e944 GIT binary patch literal 417 zcmV;S0bc%zP)=wlnx)<^8N0A$6XFU?l;N(8Q}Zq)nMgnHnL@z8KSBRn@Z&a%{xn|-d2Q4 zMH9;98$s8LZzsrcY-m~$XFnviYhEiADa-Lkz!&I><>UW8(|7X;y57kb#}^N300000 LNkvXXu0mjfTqdux literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/spellcheck.png b/base/resources.pk3dir/gfx/icon16/spellcheck.png new file mode 100644 index 0000000000000000000000000000000000000000..ebc632d9bc411a06cc269dcdd21b87574cd71693 GIT binary patch literal 603 zcmV-h0;K(kP)G^19JQHhNlNj`@k%q%HHzg==U|9D%gW$B$$pnzkJW0RZ8O~_ z**^l>7H?3b1=gURtg>1uTESC4M-RmX46)~p85(ciV2C_Fjlp$--AR~)afRMYkbh08 z4X%OwtCOX5QXyPUQYlKIT_aI_mrA_ym5}Ph590lI|1dY-e8b>)T!Q$}jyx;DP=E8f z`?4qhxtni(VX!@_j1r9uwKo$O%5S=2)f{@(N4)p$pTHGQ{xjEJf5%{XSQ;Z8FqGcZ zl3e`w2SfGs#SE#JIl*G#XPFqH&rY_S_vnAX(kK5JO0Pd>Fg+-NGa&&rR{O4h{-3$~ z_A`dyvpx*PS5LYx0%~3Y)SQ3$5raOeW=sQO&$9r%az1SBi~p8$9{kVP_~L)S!pHv^ zGB4j_(A+OUR8nT}JgFeudizi1j#vNv=0E(;kb3?$gX&%hlJWx3pG8j7?*C^R2Ufr z!A*#a0RRTzHbHkRR_DJLALEjfHcAx^ZJQaCv5 zRc_myg{0)59F#Je9Q@Sdc_JdxD$jSCy;J>({^8#4&gN1?BqC>vi&blI&zxtTs9dsc zu%=p8h(t~oGu`{%_~x_M=G}7FO*KQ^6cU-L?s)5;FWRnnq^sq!Yj#K_sg>h{m%dss ztL?jU7BrnUqbY-wDLXg3@JHK6bJ}M8FzuvqO>3o-(cT^ReKO~PIrDg@q3)QP5$R=p z|DjpW{q)MbU;cV*%A}e-wn;xl|F)~zp8DXo_a1Ag8+Xu78>FA5y-TiWxuE5oriK$H z)a)~Awe+&6v)^?M)21~{she=rnC(UkOD8Eam~qB&b#;@*)r{F`la(?^8A-Lyq+<>_ z;)nzG+G?X!hNO~6igec)RoZ2%EjC$eu_5WEkcgy6mBA7#thU^+AsM7fArcXhlB;K`2YX_07*qoM6N<$f^}HuKL7v# literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/sport_basketball.png b/base/resources.pk3dir/gfx/icon16/sport_basketball.png new file mode 100644 index 0000000000000000000000000000000000000000..f7a000b9ae4beb7e2f7a532418518dffb32dad73 GIT binary patch literal 977 zcmV;?11|iDP)hK4BUhe$KN9UVKPOxMNOv5-kgi^#pr|CgFd+|MrUGt z(8O1>C5urLHi^@yWCP5`g3ciz`jb5EQ)*Y6Fs<>YtYdi|Z$7iUj3J%5by<|2kMLF%Vl==ZZUK6wy_(+9Q< z#T14bqdL@$b8EdeIz8+6c$_2ho3Dm{@b&e$Ge3_}-Rz{0jFFqou>0@<9I}9N8OgM; z%o28~L@}#V+0e<-wM$(X#VN%q&IP>T<7}wsNzJa1pI2!+-p&1+vlMe>gj2y4bfY+( zc-#sVjvVFcW|Uxuba`lGP)X0m2=Cn{{K7LVUKplqfx{If^3>yCmJl{*$t0Fxl1*xC z=Sn!%C#m&RqbFAnDEjy$`qOa~+rr^@5@-!_>+4_XIyQiez!oyT+Ino$!0U4%Oaoj2 zvRUYlROO}6D+6fD8Rjovg{n%zE$uY*>|x^j3Di^`A=%gnY$1URSSFII2BVN6k+s$o z)0Fgz)&_S~x*a{WL?M%+F5H027hw9gd4!PJ-xtAO1(IbVTpontVdLH^g(BC)U*CN4 zQD$@H{ZL>xmBuug^(1YNgg^)^MIomax%2xPm=+aoiH7dO%#4il-IdWx(V}!xr0!g= zx-sxz|Gg35!xKFNeoH;% zRI>;DPCQAsGd&r#7FHA4(HHytKb{^=?hyV3XQ-8jhtkdh00000NkvXXu0mjfe#+H3 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/sport_football.png b/base/resources.pk3dir/gfx/icon16/sport_football.png new file mode 100644 index 0000000000000000000000000000000000000000..199f0f7f1c105db4d1da7923635ca4d1665b0618 GIT binary patch literal 875 zcmV-x1C;!UP)@uM zZrZKLQ08ITY#wSOr^)1q^3X-^zFU_|=8x~6ukZWw`Fy`03IMg#Q84MtI+(OwT`YR^ zV3Vj?^HwNTaMD`&0lplTt79Z>+eQn6urr&!LYc$xS7tL>WK7y@7dr>N0yf5al^FXV zLsw}Y7`B^#-7zO#%jvgKj-OtjYmA}ET{4Eq58sgU) ze_Mc+%rp;W7QIu=E5MLM0By4nQ^TL2uFOYUdL$YX0#O%x3Vk)D&@_v{KW#TNk2~o1 zJUcQ{Rek(IO!O`w32A=(Pd%2UB(9XD zCY7s8^6xpB2zkG~K0LdDM|18c{->}XW@ZJ)H4y#zi6N+Ou(xMXVl;FhpMV*0e*bg5@jLI;QHC){F;>`R6}I=gLXzN-t$s1{H|6% zFkP}V>jwBIwl2afcT19fK!@kT))+NX;>*FcvdkFBbFQH!B@C~lJjt{J3?{SOHlifR z2~YeTK=5R!nb8GGC14LJ9^Hl{IRxUHMzJvYpRtQ{X-ldG#PEas+&AjIl(d#PxV(4ao^#JV?>+&chcHA(W9zrcuzIeZN_*SKBfUBi{Yn_Ku88)CIy(5o z14=m5T;5${pO7EA36uz_sNoww%td4ohv#73M1nBfuf4Ii#Zb`Xkx?c^#Wj|EB;1+9 zTAO`3)Mn^#lUbsMOIsNead(bTs~hdEii`#-c%_#Z93Byp8u;Rfb|2RBC;KZL62xLk z1l1Nr<$n(?o+_Scw@RxHl?15^Rr)FwKC;G~!x?W|M;u9M&TQbFkgoE9M-rMS(BuHC5Cr@S`IdWv({{8!lckbMoyLt2GqP1(+3W4PDYCe1Rtni5wCoUg8 zd^mp3o;@i$cI*h>v}sfPnl)<{EnT|w&iwiF)o^M)bLI@s@#Du|A3Ju;1!zdulP6Dl zA3b`s_36{6u^TpQ2%I~2?u_Zvrx#$=eERfhCZNWNhYlU813JGKsA<;Y$B#EXfBw7@ zXvl6LI}2#LSAT#1CaeY=J$h6QsQJLUb?Yi`-MUo-)UX?9NE^rnK$rA9eE4u1&|41e z?d>P98n9;Tey{XN2VSpQwJPYrg9mF~zI>SrvKfe{1NobPhSUNBx4faDVFy+N7O&eG z?9;UO$FgP1N`Z=DHn#&cgPh-S_wLT8m6ersSPhu8Xp6aX)sCNw7caKiyLT@r z@TT9te}D6{XU__OnzwJ;woSXDqT*IjQIQl@1EN|sE8CT9`8{XOob$ktc3-`Eb3|G@tVF^4Eohg|=AJL2lbZDeI!mXYyuU{BM`P`n65=@@E$5OP&}eExPHN zKIK+vY3a;@f&veidKArFy%Sm*+j@RD6s~$7-+SV}bKc^tr1HtNDW%s+?`qkyWy}Bf z@8AF5xN+nEth|yFnVFfKgz^d4fY#Pl$?op%{~tbl_zz5?|I@PzPo$-#5v3XKf}G;o z6~NH`pOTSxA|)k-Xw4{Lkert3o0yo$PKss_1^|BXzSrUmnOy(?002ovPDHLkV1jkM BXjuRN literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/sport_shuttlecock.png b/base/resources.pk3dir/gfx/icon16/sport_shuttlecock.png new file mode 100644 index 0000000000000000000000000000000000000000..917287fa0ba063e436798e7e1015745ca53bd612 GIT binary patch literal 683 zcmV;c0#yBpP)`0Ff_) z6e&KX(`h$k5oZ~J5u9y)zyE$Bk+^QPTGuQV%Y(lJAkE{v8jHo$!C9#h+Aw-No*ght z^l`{um25Vfi-I5ww8;=op`M_|ag-U@4_cbSRV2wryWPHJv)M$}FCj1rIcqYRM%n`O z`Wh7 zK2s_adXd;QTrA;c|W~1W4#eyUX=D7{S)QhURZu{wV*E*$t7xfmZ+P$ zmmY}TY|LJ*Do=`RwN9cf(bdybHtXB|IE<|AeS z=Ja%Q-prWI^L^G71JLJ zE8`y7X+TRKbJ}7QEf&P-lZHVDtk4w%9mAH2<2r{UzpN1_~X;&AtPx+O1GL)H&d;Z}BMq6_~4ugAk%x{bD~00000NkvXX Hu0mjfw(0T$ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/sport_tennis.png b/base/resources.pk3dir/gfx/icon16/sport_tennis.png new file mode 100644 index 0000000000000000000000000000000000000000..e88a6efa1d04cdeb47a10bdfad46da5562c2653d GIT binary patch literal 884 zcmV-)1B?8LP)HdtBYdE!qbq|qw^eo+5Go%YI zri}HfQL{4YHLp zUYR_SM+pD;A5hEG#uyVikJyhc>OuUH*p2Haf+~YXw0D(yP z#Q*(9(Elu|vyH(=ODdkx5mLt9X6SV0s#(EJlNopd*b6`zY)?PWbNk=W%i`{rgTK z{0us}i=QdsNYlJNPjhXKpx95be1d}7@A^tuKZDZ-mxQS1ZLZ8z!(N+N zm!bN`MYp~Sa9^t*iP5CRm{p9Zgh~=Y60sr^mW*cp^&j2BPXGUM-@5B#(`4ZQ0000< KMNUMnLSTXp`kIXZ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/star.png b/base/resources.pk3dir/gfx/icon16/star.png new file mode 100644 index 0000000000000000000000000000000000000000..b88c8578956ceec4ff17f81995b8652f6aa2b58d GIT binary patch literal 670 zcmV;P0%84$P)rx?szq&Dw38OK zY!^{rCAFy_2z8TV&4=Ube7+y|oYO*02OOyb5BD7I^ZdAQt`ZS+tMaFrb6^=AxbXHx zH;=|4CCm%L{PZwSS3v3G^sH+#W3JcR_xs(&`Tqt8^J9}d0vU#im5^f#04JL4qMaI^seoYDXwB>7;oyw=|M z1!ayym?6XvqV3ae_f95{py8ukt2TxB^!VIzRRh4#rNu~y^X+P>L{SXo3_|Qqm>9wY zz(9!5s#OBElpmj4DRyjO`0`RiEIkUg%7D)8y}}Ye3}prow;JG>UQOIs{kfZSJ9bYz zskMPbH9)1H6FDf)1=ZKVfe+;jf`a(O{!9meiN~~d0iA$0qX=t0D6Ydx4#RO76h@#R z9_k7Z;$fv6G>QeZ{Yu0n&xL4%!?l}UPj4!j&Vs@?dl=y8#_IQ`5I-5a_T$dJtJ_~5 z4&186>klZh{hfba4fr z6PwPau1z;L*OuFz&bh6rTf>}7rgwL{vsvHnW-Tgd2hPI}&i8YE=X?(f0PF88s3%G) zL~ga9&rja%@sULWLY>0xDcP!aOR+%eUoyJFnDMM*${oSj3a;9@k z?EJir4=x&dXBg%M8gg?G8D(;HQb1#`kDT^wiYFX2G`0|w(-g*MDHJwZ$)td~ZXZd^ zM=)UzLmd}~FicPwWyZ*_Ba#CO>rHB6>1>>#BxM)&QmCCWKWd?Nyxg z+&=)>6*{48at&4w&G;UI(G>&G80eS6s%?jEY7r{)3Wf}R$n|zStvwYwpMBs&0#Mpy zcZ}PEP+CZgSt-0{y6YWb^gq3VF|!w|!LPVeS&djM1|sMl)ZiNDpeh023*EHA5rTNw z2NmPHj~8At$fubW(Ar5}A-e;lANk z;&I0_l(AD4zwJ0C&ELV*x0W^AF~SJPZ4|Ri5*=L%H1XLGNhEkaL_j<+iFQ#NsyJzZ zGnr}Ze-3FkcX%m-Z}8^bAObm+L^Sn+F1qJ*Yw+yxJi4~{=tg~Udf;N#UODH;zN}dN Y4=LaLNh@8G#sB~S07*qoM6N<$g8f@x2mk;8 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/status_busy.png b/base/resources.pk3dir/gfx/icon16/status_busy.png new file mode 100644 index 0000000000000000000000000000000000000000..987c806fff759fafe2a221a8d1eba225a3ace560 GIT binary patch literal 751 zcmVMm^(vTr!>t+|;*hPrMu0kRLK}h1qZtx06|w?a-}3^qoWvxT zfGus7FwBUs(l#`$Om={_&1eeI{;ME6L5Jm!CgE9<;a*I@LCbfxzsBOR;|S94iWW$Y%n_pb3sBMQ?EUhPdzat|DF7MMoo}#Odu|*-#@{3>z*~tL(y81=;uZeUhC0MNvg+l|!JR7U)*Ljd(7Z>ZlA!;mAE z28_{LFwY3!^764(ehIPL)rb}qrN!4(BV2Y~0sQ#0j&hSGU+3y+>f$g$jds6Chbh3? zZN%c~0<6-Wm9mxO@RhWApCP33pF=vU8{R0>yQ4LanH|+bX7AiR=brjTXM8d@|Cf*C hq>WTt)Lfzb{|&yn-Q8GmUSt3O002ovPDHLkV1fp!UoZdw literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/status_offline.png b/base/resources.pk3dir/gfx/icon16/status_offline.png new file mode 100644 index 0000000000000000000000000000000000000000..a88261a65e7cfdd6cc724b95f322857ab4011768 GIT binary patch literal 422 zcmV;X0a^ZuP)guf5051u^hG_WwKQb8ui+Q;x{7X%|^Y&0xPbV_6>a>1n71xJ#O zjD~@M$`ct9q?!Bbg0q&vEh;stNEApDC(Ba13yy!P+##c*P~w4W;$&Iufv}pTfQ-Tm zdG5I(MU0u=gm-*pFN%bYN|{H}gzU+=6QbVu-m7iQpne!TDVN%1_maZRwgWInz^rj-iiE`ej`WTM zRSR$kWHTx*hyeBSk=JUKdG_TQVeX5bE0{JyvV@u~P^D5s5>{3jW?s+db|lDTKTqGC zTB;fqj*8`$gA$E!<6(|fX0z`b`=!k>_Dp1l`;Nt~oamI2oIL+B0$>zlG-M*cEj-Gu z7G6GhbxY_MuX=WHbTpG5=t*22KG~LR)dDD60x7<}i*mIYa*$(UU#um+T$+%4V{Zh% z{cOt!EfID6%<))iH%0cxpsm%7NgxhbM6#gQ5TbN040g35dFYa72VLzg{mo$?eiv;5 z3j$KPDe(1gAtZcVGSS|uAQ+1u@epX5(kV+mX2~2LJ#7 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/stop.png b/base/resources.pk3dir/gfx/icon16/stop.png new file mode 100644 index 0000000000000000000000000000000000000000..0cfd585963d255190b8855a7689e8da1c4d7cf6b GIT binary patch literal 700 zcmV;t0z>_YP)*?Fk0YVb%?UEFajs1S?+YtYiPrjx0+ z+4YbyJXwz!SX#yqTlhtNQ%Ku9=RNm$j)&+(}lZ!UGGp|@|O z09YA#-dR#rIaGe;MBLe!ht*}!c?U}6YT!dfHDO%~>xtx&Klk-^WB==sC_vP4ddg4L z#GN10u$+QGf$!(i3&8VpF6O6+ef~&gQ#>AVqCJH_utvKMAuOeG%3%mn<<%9)yb~#4 zHc70e5sYyQ03$?zFUko7D1Bg1=6jXvg#bUm1b(pVKuC*}koEKGdj<=zdM#RWsl+kfRf;OU^G_BQh+Fc$z&F_AHuQYu(b)aq=H_Fx idDl8IBmWBc*Z2i=4uSP&;Q8VJ0000p%S8Yz4}?d^ZEOv#Sc!)mtIgHXaEQ+_ullV zJO1Y8v8UhuAAS7ozvIlitK{;}YszGvVI*jPQs)gu{RuZGF1qsJqxF>Ai*mOY zeUVJ^Xn04=g+vNN2-6q_7DHe6!8fa@! z^ZEB_2Vebf-umoI@{HTtK!PIfdyIp7Zk$|p=*|D=N%#IIE_w1_EaGe}ST5wWclgx% z|Fx4ZY{8likTKA?G12oM|4&}@o+);3yYs=L?ao)At-(S*$63Le zJ&q^>ZEbL?y!O>L=h9<7rvvdA2Do?L{p8zs_rGt?o&P=^cm5ltT|5S~l@laqmU8i; rSIv!oK>XjU`o@3v@@qdCD9z3Q7_5=EFk?|V00000NkvXXu0mjffa;^e literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/style_add.png b/base/resources.pk3dir/gfx/icon16/style_add.png new file mode 100644 index 0000000000000000000000000000000000000000..e0369c6be9d36e994b0de011069494460d96a837 GIT binary patch literal 844 zcmV-S1GD^zP)e0@+Julu(JNEkTghQ`>*6)1&K56lT)AFSk6p+=zFou9~?@f=o z<8N*rd;0DF(Z}EZJI=hjN-qDrrcCA;MuG+?b>3jqpKx>HqAMRhT2HyXD0l0#iaLPj_0@CCfwX2oqfq#v-#E>^WJ+0O*-%H zHfg=H+pP80LCw-@%MhBYE~}R8d~tQ=>345r($1Jk$Dh=ha`5$Q|0%Z*NM~MfR<5`? z*=OG4&)FMa{LftT;=fMmjdkL&7s}uU7`0rTx%v91Kl4t$`!M0as~0m4zJ7b)=BNL$ zv+kY|^Ex1>-*9Vvz`RHQoOC>ZM%CJXsdg~+{gcAqR#h%!vGjSdf96p zUz&8_)hmghBZe>+iF)o;PnvP(V#cg{58Ni-fA2Qo-b=Bl^VUFHgCb`>{I8mLVHwzf zj-AiHPdoVPfAiL7Uy^6s-UbpBao=Mc+;ijPvO{nFM^C!rXeXPW->+%GCcCp6&YIzdP%Hc)#v{<8+;QI1SLuzO*J`-lP9w z!6%zz+g-kIygcFm#%q)QgFw%o)c^f^(*K)hOZ~vm2n-}+(aVjYFP!CqB_qTX zOJ&0en^&%FY~D`yo5wuXrqeuThwbe*!4lN!gNF~E?|Yv2;o&s_0FxcK)F4Mv>u0z* zJhiT>SNoIRsri=6U06{-CYN%OHJ$srT8APibiLY-K*7FMO` zu!-u4!CmVjT89blRPxkIDKC*hn?y-keBB&eC_)C&se#e8D!|7|Y1Eu$<>Pfv>N49K>6fy0A2YR8!Poer$)vwrolN$#@;q4<}Pej2{e%3 zI=@b?o@g_YM+14D#L_V#yK@oZ%9M~)Hw)Nk$>Z&}>!Pcq%1JmymbL7=2fKmBjgNb+ z0y1kBXpaiveUuCEe9fUL91qlp8>1G%-IfQ7F?q0R5`%pM_H zlBZRaI3ut~u@Y3I*su)iBl3JP27{y#cAw>392ogM27x8WYUncrLQ548Qmg=v)c#(M zKW28lmJEQ3zM`w6LouCZ2JeDx41XWS7nLH=8uZMsJl-Y~+6d*|L+TPovcw00000NkvXXu0mjf$UutB literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/style_edit.png b/base/resources.pk3dir/gfx/icon16/style_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..25bb5b677f89b1071fa44f29a006ed0be8fca098 GIT binary patch literal 927 zcmV;Q17Q4#P)4 za;GYM@Zfsyfm)fD&Ry41qf>=r$+ULd=aUgoB$PD=lkdf_7Ilg?zyQOl7->rK6-vac z;TV_Zv*2yTAsc({lxwkakt#&M=^sjC#7^AUP&&Nl19N&`|TDi=7JD}Yd0Ws1C z>4Cn`%K-NAO-Gb$R zVwgTXc$E4*bT1D$0aYNf*Tq)K^tV$NSHqh(`FgCPo#PoB*clz&@Zz?t*3^<<*(b1GSS=liGL+!XKb`BrUt80E|` zL^nZdavGLlE*g6AK5q89fuGJSBa^o|%9F?I)(M}uC9Y*LTOPY~cz<|nclXlE}xo*2>>r;3Jd?&=tr_!Iww zFvhUfzU@K1>#kb5wJi!Jl*ja3{?P6ZuOx9B{{rz!RGKb8<;DO2002ovPDHLkV1j*g BxhDVs literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/style_go.png b/base/resources.pk3dir/gfx/icon16/style_go.png new file mode 100644 index 0000000000000000000000000000000000000000..25d6181ac9f814963f515c363bf7dcfe6bcb0a27 GIT binary patch literal 862 zcmV-k1EKthP)2r7#xK|RPpjbh>wel673Rj41+4mDY(S62jvPf{cq_v-ek|xTnHW zcy>yBKofFot(G%sIo1G#B%vscr`XiR&NXTSkpSLxhuVKlq0b8fvyOFFICMGFVJx`o z9Z!=OMxATr&E12nLGp!$En9SU4yb-$Bs%I$=UqQ0;@>DHH#uj+XO1BG@b#0f`j*b% zo8Hdvx0MG(WnybQmvf0{fLEm&_Y`L7>wJFk>(D^NoodoN<0$9?4~r423@C43b=vt~ z0*?2*oN`Y*E_*Q9wyl*&`1ywsVT_}Uv9QE^%|MQl-1Pkg6v=u96VUQZ`urNt9<+Do zr|^ZdQLNirlXi73nNsU1DX+HO*_mf5iiqH}tyY^vB#3s)dZ?;8(n=J8hK1z0zs%x8 zT1>1K$0a0CnB(M-F6V97!xY3?q4QI zJM^)H5?WbPBLbE&q$N9)VtHORIqL_r!3rM(UC=%3$HBg~Gs|XB+dLZ9sKLl-cY%l` zKqR4blOUOve74k81AYGY&^6=(7kL5%b7;jOE~VfKJH5%V!}5B_^8pbkn`lx_`d?dE oimQ>CmWj#|C$c)&MDd^eZ)gE}if+w3_5c6?07*qoM6N<$f-cC6E&u=k literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/sum.png b/base/resources.pk3dir/gfx/icon16/sum.png new file mode 100644 index 0000000000000000000000000000000000000000..fd7b32e43bc8128181c1aeacc2c1b0af9dac484b GIT binary patch literal 289 zcmV++0p9+JP)dEcNn4H`bJ0C+qr9t=q z3IB5(AiS{sSlm!hKmUK){R9C#j!Zc}`+sBs9tE)p5$}U$;ZzVK5OzQCHlA<@UGIO! zvj@U9`H!I>IKl6{$7vAD0_aTr_h<@&41C_Zzj3U$sWlFzu{fRl=l_3uX4QtyMkj+0 zY#SOnetv##&Ac*9!Aw2qzO90ukB`rtBTS+*)~sK@Qd3Wl>6w91lc$EXqw|d(p7rtj zL#=9mJql4^&ui$IAYgxZvAe!x-T!~wAEkwbV}v;l|IpFV;kk6_P=alNz5|0Yv$3)9 z;rsjlKkS;w>nL%6C&hSi8{-+bv^22=Ol%^&FHDS$JJJrBFsN`$`tyH2>+-h(-T}M` zbIkMa)w8ljvf0|^RyP)a!RbZ^nygOjY zvaEgmwz2N_`+TjfUI2su5O03fI=3GN zO-DxyfY)uofj}vRZ5#J+ElHI?A*K4L!FxreG+Of^;j>jrB82=(AcRCIi81=y>WNH@ z%WRC|bAfWDj8}GRun?h8$n^AdF*G#bidPlPiBA#-q@JRT_(tjU^l_TnC4PNQQ?cK< zK{}l!ozDLFW@ou==4Pg`rH#LBisPFd#s??Z*^7WN=GQg5GHfE(Tc#HK$)FiqXft*F z#C#!FO5Mi@99aMa4lQnTNq|ya1TW@gEuM_gfac(8lLn!QCe8qYqTX>HUu+Km^FSj| e1UBOv_sg$~0hzRbE)Q}50000VjOibLw0u`97udk^oE-nJ*FfxKk zC>udT*o+LXU%yp4efr{5AO~)Mh>#FJ!=pzp8Gir%3-KEh6I>Gr!}u&LEDX}p!eBjc zFF*hz12Z!-!{5LE;fj$BK^VXcWHY0N0nA2bW)`3V1{4kGG&3`ZX2LW8BnXoH|DOe` z?Z1w%Vfc1rIm54K4;WsHN-*$Bn*;SGGBD1YH}AiKf-Hlco;E!25CI0^zuC2r;rrQ* z4662l4D5>94Bs#9Vz_o>FT;IqU5EjM;!J!~6@z1HDFf%-0}KpLk1#Os3oyK4k!Lu4 z>^cJjC@&Dgdz@JQ{X4tvKQee9-48WwCz=RY_ZJ~6X0ynn~YaOWu_Fv1z8F%p}dk4DHUL_z|9*cLd@B00000NkvXXu0mjfcQ48A literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/tab_edit.png b/base/resources.pk3dir/gfx/icon16/tab_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..4c09c0fd702ab11802c4b14cf51aa478ab8e3504 GIT binary patch literal 580 zcmV-K0=xZ*P)GaTv$cZ`CS^eoMHio&-;eKy=l49%&jMKf1j|1aEQ}pE z9vwP~`nZefyGNMm+u!`#;l+tPjhbL(W%en2%J6Y^6!}W+d-KxaaMT#QHQ;AF8}1+% zx=3kp98K({7<|N+gp1(4HhoJF_WNbhY1Jf?sW87uY=q^|1a;A#G{vLic;vEaqaB!F2-Lh}}&E>lF*Y?BG6Ki$V|MM6AieLky^#zer STRB|-0000}QD-v#^of`t8ol%E>>SLB14q9p3NkwX3|5@!@8rWb+j zKGBJmy2QkcQa}UehH7>3bQIt=s3TxA6y;UGTiArh*fR!}8qk|Fkq{6sz{|@^k(K3w z%jHs|NCEqpqO)ocj5}Zsg9DDM`v_`ETJc0*F&`PpL=aqc5DG;UzFLe>MZUZ{hb6kO z9Sat-@DP7QZD|{xtQSm&hCqJ%3;hd~yxTVUEhb{&Mw4$WDDyjt0&Y(-LC>Y za~>9>RP2BvW>Zv{Ra&#B3%lVhY@Dqf3UcFBfX7L?zp;8!i`JL5o114Fd(=UTAXByc qbOk))B+4A!e05mHZ9qIv(%t|bp11egU=P6n0000>q?GuNnCdgP^*Bj5V_b?dAq2Ppn9^MBB^YUM zad0N-T{Ujg*A6d~mYV4na=hT4Nz+_}SGTgW|Iir!%$ z;@OGkWI6+j0H}~K4RYR%!7y|zM`O@*K>rL{*&}x3lR**HrMXC1->#slU>X|w!U1xQ zqc^@R5;6} zlTS!gQ5431?~i{f-N>j^(nf@gnz4vsG~1*?ZHy3tqD@4b(p4K*Q47IE5Jb6XVMKux zSz4`PETXXnBWf%+CAA199Uoz1qRzYL-WG3|8Cw}$xO|**x!?Kjch9kmG5pVR0q(w9 zyl4z(#pnjDHKIXjjfh6HL5VKef+&M%{dV9~Q`7~}#`N_>t3&@%`O>}Fa6y4+9Re8t zdK;w`N)*0U_~I8)RN<_@bpYR&iV}jrhm*U`Y^eJ3s=`-N^gu)dFp|h@h@g9a4Y^VR zl_vl=(O$>>$$5?+s4wJ3lk@b%im{hnU9Z3wjW!0?fzdY^9LMHiGJ|DuWY zbD??rW^(>tPcVS%SR9MiGCsAy(P-T|1*P$9I*U?zy#k}bwc+Wz1so?p2yy^dAKl^m z`~=G@i>&!Ma%=m5);xjI7-J}N;PBpB;wg{LNU<%hjSaIT2|5l&X{c%9#mpGVPmhW9 z4qve$=sEz$wuq-Z0OBc+c*^7Xw8#6;4`|sLL2MziwF|L)Vtd*E&Ibfa1s>SY842M! z0d_`0914f#Z3A& zsdR$=u3HQ~J58li0kE3?1v7bhwSU`zl2002ovPDHLkV1n}7B%A;M literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/table_delete.png b/base/resources.pk3dir/gfx/icon16/table_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..b85916d921ec08675f9e41f18c0fbfd7f2124d8c GIT binary patch literal 660 zcmV;F0&D$=P)Q?2k`9nO>z?V zkm+%pXeD(;$AS7ZfflT_L=+s|TT1_EiiW!ITMXX4Mag6@HO(#LRPSW@V;_Y>1H5R6 zv<447v{ZFFVUNY*Dm}RIv2nDFsh1@_Tuj zC17D*VH8v8SFpp^y1wjLHB#VfgRc!n3%(Jw(bShWQjmB~tT+!(MOc{COw72}B6pni uj`Q&8s8!`!6#=Xdf;B0000P)5jnv(m~oD{XNgT3)4vA_BpPAR^yYtKhdYt0F% zRhCi;sX!=&lnSXdLaG^CB85gO^}75>ZomdmT9+LPq@?{z=d(9HZcH$cN~HnRbYDRz zfsg`M30&z;S1A&AC%2X3x-w}7K-`DJ>yH0b_ir(QE9A5XQYrwdgM)v3=y!r-_us;n{0~Bx1NSxhn7-09ZmqgoMF?+)iQgb#j`e`+7534TN z0IpOht+6e*T|bCrncQg@#4y1G{LUj{Bc1qjw-f1V#cMdE%w2?U!P3-(1P$1h!NI^n zYF>po5J(3gHuQ{%fmY__6fxCz9dEM1=f*ao6DG#gP`>$-fmUFfQ2Qo~WyR~0Pz{s) z_nEh153w(m7@iS4z7&$=Fjpf*6qeoThyw_P)*6om`?f4(mTj;#xt=vi^`x%cPptPc zrpLvJW-}CQ#wj?(S8o;&mxxet6D`xAu4xF>S4X5LM0(y{oc<~-uVyN`jDhEG>CCGD z|Ek2~;!_YJ?tux5$LkQf1)(zOYq`k$bT6^U5=P&&kzGi+A}aH!shy18Z~8o~aj;gW+TQDw?~0 am(K6d-%A+Xv@1gZ0000G~lwc44+E`q>jqydsX9IH6-SKYrQ41uvJ53CgcdPe5{3UH{dfYo$>`2hfE+ZW-+ z=qyK@qHAx1qxUJx7$sWOfww-F*ka<>2?8sKD!vCdAJ5@=E`3kta9r>;!Op~8LeVCk zjrK5~+d_F!CaXab;Qm}e0pD|IZH(Z%aHJu^;ra+o8^?(h)seet4+YC39N4j#{8}R^ zKwt$G@Ljkw`5Dhk>b<8^e46ejC!B{}yhXUYjj5q-tT8C*03)a>>pW<#EhOYSH17?w z+ZiBQ)&hy=j9) zEY9ZRLY&RZj|kF4V@iU_JY`5llj VPx0FJ2v7h3002ovPDHLkV1gP+HZ1@E literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/table_gear.png b/base/resources.pk3dir/gfx/icon16/table_gear.png new file mode 100644 index 0000000000000000000000000000000000000000..cfc2702acd7b7c84be4d84363e6845d4be5614ba GIT binary patch literal 714 zcmV;*0yX`KP)KTsd(L2%Nfb28ake(Nc)gcnjiHl06Vi5zr`8 z(3F?(m8sa))$`m0WS?l=+qJX%?3~|q&b{3f0P254(UJXrb9jGiI#k0{pbFjlDki*T zsNK65bM9bxejAF{MGVvdfg*Ucf>99P^0^-hR9&S2%@qIt{DU3aL~IrBX@O zh{xkltJMZF!Qku$_KzEIr<%^br7DT7!cwWkIkl(KYIP_Ui*UJIkjv$u`d_XSfR}Cb z{UM9R0=L_ZLZJY?UJqxoLZsE{kj-XUkQPFr5LDmuPuODtfppV3xYCS`Mgz%Y5)8w@ z@Angkj%{{2orpvt5Q#*37I1~SZ(2p|=nR#EQ|#1EP^{GPb@v#bw+~@78VP`#hFgbg zG?`3@Mxz`6VzKxVB{AfpV(m)(_QW!7K24!#B!TNn23O@VNMzIK?d?U6)DE-R43$cS wYY%A%1cIMD9`7A_#BRT>L?Qv7&&S{SUnp5P#YQSqod5s;07*qoM6N<$f_olE%m4rY literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/table_go.png b/base/resources.pk3dir/gfx/icon16/table_go.png new file mode 100644 index 0000000000000000000000000000000000000000..0528dfa24ea76e6d1ee3919deb5b95a6c3e8b27e GIT binary patch literal 683 zcmV;c0#yBpP)&Lm&p%aeyiM6U{&J)Zzehs6~qcg z1!K+DX=Sr^zrF)w?A~pFj1Mhkw|6ytB@m3*Ef1_!0J{5Ay8>LU$tBzlkaYmSjnfHU z4a{=AA%8R1Gc-$c-Bvue80=JFtfI~l^`U1lh3|Xx4yA~A;H@{^>pDl;EYVc{nu?-B zgeC*uF;DGCO|}YDsT!>58jRZ!uO%| z#aWyhLKQ+0j^vh5T5yV`V1?G+DzbUD4Iqkhjw~N8oy?y)Yaaf}M024fA2YfDrYonhIm@?o-n z-UASkj0YZ^uZk1(A&>yELViv$1v$q!d@xCtA0sdOD5KK@e4O~oYDmqN2hLGZe1M<7 z(;Ux_k(M<&2Okq^NFX7}co}ucMuw;Q8J!uUBKA~!+FL%aKO{HM-aTF&THSBNV#E@Y zZlYEZE93y5W*UijF$TuJP_pL<3oD7Y0Fm8(=VV)C#j3wAtu~o@R5;6( zl37TUQ5462-_l~GmD!jj5v>qoD#&CdZL|ncl0r}@v_nv@(Nole_8x&x6%kcZjNbMBwtJ?C(Yi}(AFYs~?vRk2bEsX!=& zlnSXdLaGrakwPPtde&IK$Om96t&i0Catrv6bK=UoWq5(p`9mB5v5 z)=M$`c5Fo>t}7>u0B8VqE#3D|zsHgSS4gq|sQ_qs5dJ5?wu*exBLQLv0I;*lL+is3 zJ607A=lqXD)Kz98$ z0Kk+|p#j@6s9WK|HleoC!*-vC8lMM%8lQ*N6K=6!R){%OyQy9Bnioxrs{xEtZJ+d^ zO-0=A`GsMO?$Sx{X*lg=)O z4W-$&xc%}6i*o`@E!l#McQdh|n568ZXieE95$kWZg~|-kG7UPr9DreO8sIAEi_c(M z|3^&A!7yWt&vPIdXYgCfvV{;f-+m@oP?$sT`ylf34UErMnYX+OoxX)3qx9TNVI`9!Qj(7! zBJ~X|LBB1fet5FwZCP5X$*z#NLL!CY@azuC*KZ*0G-KOSd37hvrB9m)=T$HmjdxtT zP~!(cYdxlYX{&yc3N`6iV5@$9dS&$No`nr#>FmF)?AM^v85y`cFa9%@=t@@v-Jo56-xpcZCLFvFo+sh%yoi{VZ?9B7cjqH@ z8!|K0K+I4z)ErSm)DSg96%|L#evN4{_Y+flvN@i^7vC@LifQSMZsr<)pJA<0#?&w| zOa&KZT_b+%+Dp|_hzX*?r~AGp1Wm_0Rk|^m+?;%ybY_6erk!{YJP6vXQ(u{gS1-+DVsvCiz+&=4Z_!gK zprJ`^=?3>+I>|eGM~G4xHY`4{oCq*90 zHfq~Hqng;lg=?$CiB$~Pv85Boz}<0ozC3%&%PVDHJU8YKX5RO?@Ai3R;RkPKA6bUws5yfGJ=?vs`Qc_KTWo0goouiTL-$h^=J)M zL(O?@u!DuWRi0($mT-4AOn)<_L=-A5W!r^l6;r`F>{yEp7wdQ}83!rCswNq=_ zq*jNNQb+|tDWp_Lr4dr4g+vOCRBEEDwY1U&ptQczSefnpm(CAfhmP(LNTs|0gWq2v zlt4&P#};uo!MS~DaC{N8 zCc_0sd|7PSe?371F2g}XWgdg$NiJ9B?;%LfL$Ni4Pa&qpcOjIeH(99(9V2I`$*Ld>uIkVFf6crZY_xlO|{6Tm3 z1o4FhjvYTmZOwVY;c&YXKnQ^b!l4;FIR^oF)OinK+qAT_P*qh$eSJN3b#(~arm3|Z z0FTGx-t|Ch%1aM3{dqDqst+F{gdh+IV47xXfGi886g@AVaq&Ve(P(tTp|$4j%daEC zmKCeXd2{W{Th5-WpxEalE7M6Lksufh;&!_!DJh|#pn%_-idb~s9v*r>=Scs~Wo2bX zQBjfKG|hqH;^I8F+id{OrKP1dAnNsc2Y`&t%}p7L#gdj~HT(fFX--g%a!N-40000< KMNUMnLSTZ?Bt^mi literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/table_multiple.png b/base/resources.pk3dir/gfx/icon16/table_multiple.png new file mode 100644 index 0000000000000000000000000000000000000000..d76448e34a04f5c94794597f91ade6f423b3f6cf GIT binary patch literal 612 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 bl|JXclv{aX%Z3zd00000NkvXXu0mjf?NAwh literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/table_save.png b/base/resources.pk3dir/gfx/icon16/table_save.png new file mode 100644 index 0000000000000000000000000000000000000000..25b74d18f740ff208435f72333a1633569c0e833 GIT binary patch literal 723 zcmV;^0xbQBP)9=EBdhkBh&jKg_`&J(Mr{5K9?YB z7%NS3^ZC#w7o(tnOANaU&GbDgva8U-z`c)j6qd7VU7r32pE$mM#UEBK-6|qt9$Fs- z6>t{%pB71ynwG1c@8bc0>raNK6Dt8qRVe;QF-EXH2&zgZfzI{KWSyaNeKXb?5(OWH zv)$_uQKBdbLe2@*YL(JNiVIR}Vqy(9UXB8Al#S?e6$ef`OJ z*^@Dj?#>2+q<{qlHA2?aai;eJ-%1m>7t)ru4w<;#O*nKUzaX~*8Diz*A!^1TLczbnd@cygZQu8S|yQc0M~PHm=T*UUVeXvI&U+E-jSmPDu1(PvLywGr8TgQ=M*)M_<+{4|1yv{5RR4tt*Wfq6tg zLV{VqgJ)69K=q3ablpCL%L@Jenx}`>=j@dCAobP_wYPDAM3Q7fL890|4 z#q#quqV8u*XLE?fV!B9yx*?fNYUt4!L!nSOsV9)M1v7z%l{QTPbh}+$%sJP^lBO8; z3a;zI^!V?C5EafH8AXH{TZL+c?Yyc{Q!(}Glv$=hf_>95_YL%VJsl5s55{@|)lF+a zE1Wu%&|-!|CLG7nKMr>flBfwxtpR;Z@85+l-@7=lHwt^xAuTMJrm4~2xi4NQ6w;oW z3%Uilc5~@%))oFv^}-Y;b^wV=Wvg>0lR-QlN3+>PwOWO3+gc~WEu+sIv|_QikCLa= zhy*j8PT$UEvnZF#sMqUrl-p3mgx7y17`FNO`B^GjA)LwQ^N)kMUmr-cdnR<{ga7~l M07*qoM6N<$f|JxSlmGw# literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/tag.png b/base/resources.pk3dir/gfx/icon16/tag.png new file mode 100644 index 0000000000000000000000000000000000000000..e093032a77d0b90d3a5dc05759dd6bcc2ad51715 GIT binary patch literal 389 zcmV;00eb$4P)OW%^N^ox0}MJJ@O#dCdMskq^A9kwxXrIWcrSi_3?zrw0R6UmLLRf9 z9xK}R`oI6&r}tpuA*){AE8G3%KS)ly_Kpx%1N2(%MMSTD`Mq%KtN(tpp59Y0xFL-s zCmpcp**%b4#M0;AfpQTj2Iw~2WeZ>a{A1;gH$Vl?eyiqOGe&o+X8A2+kX-4em;VE2 zKK`hXbcGGY1?t5&BSPmt{hqbz#ea{!2lwRTE=eQFNqbLybPpsKH1pASpj-sjFi=dn zB4pce=UD3Er~h4B?!v>sYto~887rRu2g%7rUlhU{3o;QG_$|wC9`o+J2ag5+DGxu` j)ZRG;k{c;WnG_5FM|sxYY1FNa00000NkvXXu0mjf#+s`M literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/tag_blue.png b/base/resources.pk3dir/gfx/icon16/tag_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..9757fc6ed6597438eb8e5a70a1ab2402cdebd5d1 GIT binary patch literal 586 zcmV-Q0=4~#P)6YY{78#rvt}vj%qrc zN=UU@y$E6COaj9&r1NAlaUpajQlL~SorN%pOwHs*2laYgHBA$?ZOd~4Rw@5yFm2?1ZIg`0V-$-;GT1Fi5dB7wUSNi^%`^Ge62m>OBeX610Nsukl}DhDG-mxT?nhyYH!4he7Ri8 zrq0Ti&UXUvqX&F@JcJAe14@BNBqAY_QZAPjF(Y3r7P9H_kB#@LgFAf>xz>Qp&n=|a z>ro1XLZK^nmO`PRh#C2OK0ktd7l6-A;O5?fz1gNnCX)yR00~-SI9%?%=X}23bKl`4NrEVf$mjFO<#Nbov&dvJ zNT<_CrBZ7ExK+Uw3I&YEL1 zq(%qHWHR0F_n|0?dQQMtEQVk(xD>*X>NJrR|6!IJgTVluzJkEFiIZBbhHyBHKp?OH z;YfLEc{Cb2#_Pl@g6c zwX8?E)9I*5#h(iF=`qaGA;gdY_^%U4sZ=5tu-olxvtB}>ke2l*x7+On$PNQM`eeub zw>sQOtcA_q_1U#pC~GN zxfc`_zq*cJS5eFyM^neBh0V3}>eD$_#z~y93x^BudEejjyyv`!5k(Q1Oa`e`3dv*= zi9`bNcpQQtAQp?w0$`>sCY?^B-|tVXYPG6B!r|~#2t$==L8Verl*{Gv2ts4T1p-Cg41%^T)c)i|3Aq-XBPb9^Eh~-MB(?O%%1HUtLQYw|; z_xr)~`~-xd%KMgOSq3fM-RomxYk()80j@IKD;A5?1w0eX zO8_7BFTq~F0B&Ih{IyeXKfVEz$#iz?L`i>Ij^m_Stu}(_2;{@7O(gElqvL#zLDr4E zPj?Wzbx~#))VC+@m1SA2+wGRu@+EI*AlQZ4U$s{{4PFIsxvodT`{7+wFD@IcbRw7dsPL` zqN+OerCF_3joECLc-<-@E9d2JYjfCrFoQ2E$G|VCW%r`$A@jfIYBU-(27}>DVEOcY jqWG2CCjT8;O!xl+&v_qytO7mD00000NkvXXu0mjfWRW`K literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/tag_blue_edit.png b/base/resources.pk3dir/gfx/icon16/tag_blue_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..2a9f6266ebbfb023c9965cac87924611d3242a2d GIT binary patch literal 748 zcmVPQ541JUvS~ZL`~zygnz)KVWCC?F5D=Ikq8U?h>6CXAjX9uM6jBuQEWg2V^GsJ zMH;n{ex$Xn{j#O)Obd}(%Ft$twTjfv*iMJzn?agT3X8Y7bI9*=`z7{p>R zM59qeA`yhcVT3{<1cSld0H~b~Mbk7SN!oHUnT!JQ`FuM-Mr_<>gM6Qt( zaJ${xLMS=1+$_7vg+L$>Di(_nMNz5CK(E&ehr`hjLdmWhjYM1~ky$|ykSmI?Ev+X> zrBZOYT(H?}TOgF|yb-xttwI)mFG;vNvxdGefR$bUmP{rQusp)t#2L&_^&>KR9MLCD z9Tb_7&*$?>Q>9V?N1O-4YZzjH;W(g~S%>_|OoFp_Vo~nZx7psL70cE|*gv zi60^cLK3tjfhp`nfw={VcZ2_S1%<#>%)aa*Bb!S4U!4hV~9@te7c zr1k{t#!*?UQf{ICTBfI`)#g`y<;2J9B=#o=3tjljp2G@BGXJy%7Sn6!^?Ft98tVbi zF7NG%f9OTj`~Vq$8%hi9C`5Yjb(qASn%E?62+$241y<9T8$Jzt?;d!xt#E0M!D1ZW zB5nxiyU-+-y^m4$KZL*kFm#s=z^osIPN!2fe9HBOw&q>Joz8=zZJ<@O-aq0r4)vTO e;(gowO#c9xAttCU0DR;C0000^5T)AZ%#@G{_P{NCN^P z(J0zvSn~SSm(Ur);-M~8^*;61*VRI`T1BN&LAhK;sZ>I-SVW;vfUfJv=ko^ugnc0x zhJodBxe>iyk3%w<%wC8holUJ4(iv>tL{`DQt zPOsyUbO_Cmc&*iHkqbm3ku`|GcC^OhF>jj9W*GkH;^g!iUVpib_h*=@udp4h(P+e*zL_~ZmJjh(y^BxULwq>9zXoYE8sq{#pN~U0C6!8vY)5N2 z9P*}mw}7X$O^qTtJef1ACWvJT9^wt-)Zh0r~j#0bT`f;-zv6 z^Tmw22!%rMcs!TaUX<-8s;X-B`+Xbo+_uWuFa z1yIPc?DTrQ7KvRhmt*TG|L=EYQ=LqFX;=Lp`4}jx6BE-@00000NkvXXu0mjf=s_29 literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/tag_orange.png b/base/resources.pk3dir/gfx/icon16/tag_orange.png new file mode 100644 index 0000000000000000000000000000000000000000..454a59f30ca04916c30b5da70821b236df7dd934 GIT binary patch literal 586 zcmV-Q0=4~#P)YYm{!ci%zG5cDs#MtA%E>iAJM=dcBTXt#$=Kxm1c}S>T)> z)oeDCkaD?v5u%VY38vGjbe>Em9)x-#1qy}2S%^ZB=`y)dqgt)jH=7L{$B}&kmP#dL zv)PjngPi@y?F z?msb!MgKs27C;q`$Nl1^87)}9-#;n72%w5aqyBI>%t#yv1bin~`G3EwaPlhB@q!hxI!PKQbx4SpL{`r}VmgkO zKJ1rs_WIV^Cp$u~*F(44MZ4WbtJOlY*+iq!K)qf^tya4OAlxdU)9GNp-=EcdKIf2f zxqK5MkTVHpvl(}uPNxop&R7Z*3Wci>fg)2gxzRzjTCMB44$HFmIRQ(h60+IsMTkJI z$3`aJvdFXbdX25Rfl*oUyUApNd_Ip%CUXW6$oUxAwr!Budf7tzCgJ6?1fzU_jK^b2 zfn+jy0uk7ZrmCvEX}8;PXYF3X>c?-ad@8i>vI7~7Mw9~4Xw-oSl}hCko6%Ghg*TZa zojb2QDqe$2yuO1BheJw%P$$M1@gl$?5#tJcsvfD&-d}drYvCA3ZZKYBvF_B1^w22%tHlRHzus60N_IkZ8=MgV0M=TZ-Baw(nn|S=hBxdI) z;;R6va5(H{FKyC-4F-dY;+p`fU@++R`~4<~Jsywi;wt~|cV(__CjM~k{x92pJ|?T2 RMYR9`002ovPDHLkV1iy62OIzZ literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/tag_purple.png b/base/resources.pk3dir/gfx/icon16/tag_purple.png new file mode 100644 index 0000000000000000000000000000000000000000..ebaf0e8743fc33cf152cb7694b865e8d8adbfa90 GIT binary patch literal 599 zcmV-d0;v6oP)GWQRM3$+Tx>2G~D3qqtDdzLJ$P+M| z%_5OV?1V_vbzR8Cf4JqIVHo)K^%pXcv3TotyGW%{h{xkw5Q#dkEiV=ekof!9z?%~d z=g(E7!z)Oq(;*j#L?RmyiObN>-n-ERY$OQs{fC-WE z`TR3JBO8xbMN0KSbiO^m!^f-pEr_bBgH6ZV(+;jrKl87%5H3QY5S&iu(~XVt z`Q%tE#s-6d3Aucs;QCb?w-;^voEneC7ITEh5sgOWa5&8962;=`54d^#1;35CDRwv< z7ITTajw2Wh%6`9}(Iu`wF^PG8L%bJ2;q&>deAA2$Oi`4b;)4JRkH=$mxm=9IcDvoO l^OXPhyYjA9E`GA_{V$1@FaBct0}KEF002ovPDHLkV1kGx8r%Q? literal 0 HcmV?d00001 diff --git a/base/resources.pk3dir/gfx/icon16/tag_red.png b/base/resources.pk3dir/gfx/icon16/tag_red.png new file mode 100644 index 0000000000000000000000000000000000000000..6ebb37d25f58c68246d8ad6a015295dfa5367870 GIT binary patch literal 592 zcmV-W0k7R5;6p zlgVxxK@f)LC45c9TOf_{d{!)DV#gQ9u^lTnR)N?B4hRsNK&)mFLI{BXaU6RP-Hd*B zb;Jb3l0#jp`v2;$?rNpgYN6R|qF%3~R;!^}t)fz?pj!?Xf$9L#$Jra zV+qOU^Cuw+btb`RG?JZ%!=VYGoN$3mCUX>`kYzed-6&Bk7R#EZfpaeN1kB}fNG6j9 zAqsWf92DY}usm8Wm*DdmSn7|g4F&_G(`h6Ui9Luyoi~=(>orKcUM#@A*}%S@gC$>N zt>5pH3q+&Q9f%@k)E7cPhZtkvGtt>@1HZome|iABzA_=bUXNTL7z~;arBEn*5i{!Z z`TQ^BwFP!@4*qZt{`(pH*W(VP+wGDI_d4WAzVcfivW|vfP^h0000QiaQF5iW`b6E^(ZmMn^kdOo-E`onH8J z>I^oDOD^i7tLp#iuVX0<1_Si_eRR8BbUGch+ikR3Ei{`=G#ZU70Mez9dc7VT$2p4m zd@dl>YV{&SqRAvsRaHz@6vc&5j=MmqR5}Zh$TBt4G)mO#_2y=?fn`}DPryp0f_y%I z5+c#mT_YF2aLcM;7%2yjikWQx$AQIn^t=DVOWSS;S{So@FPhj^qFdn`O&<--0OvnY|@wf|-YPH%sz9Z8# zO*CzvI(X)jneq*W`tt}f9*@ZdB9VxI2uitJmidlswOYMG{`5KIBMjws55m8-gs2aP zLvn#oD0JoSQYaK;z9U;Mm&cHYA7FRacp6>9u`S^unM@)O2)sRbQNEv?&1TtRvDkxr zfPVJ{f2X&2F*f^RkGsNtWHK2!l}a(X#8*fU&-Y*9ScWV1`~4pG5le8ujv*W^`bq(deZ3B7hB~2~XTCyZ1O;cQ)B1udZC+u$StgkNJem9(+80{W^ak4$r zssW%66N!3M{XR?-QICiq>aimHe*MqdrL?~k9;}zz&5;}{t9NlCTfU+yw_XaW)Ch4whj=bo>I#_Vs6a)#}JGIWNaL~IW&KV7+rh@w6q zqeyD<^tSp;x2rf+j4_xmzWv1qE+$Zq3342N^(Z@89#MUG1~^fiDr4c0`S}IXK@XQ% zHvj1p{<^sONvG-0)W=J?X0zSO<%?$h<`V07dt^>zfOIP#7t)x%Dqs7rGa}Kl|zX00F>> zFMph>SIQr>nsqXP@`0y)H!7nnulA@`>O|$nn~&zf+b7SPczgGU&P=O-3Bd%670gqB zR&A7>`vby4iK&BQ)w#D$eGU*@`syR!nVp%dR;q05T11s%^d!K0PpKG@#4)`+p;(<_ zv{pF*5CSBb1{+(u+}e0Rk~WyXvPhg{I8jn7SZhg>lq^YESze(ODM8Q=9|N4VSWz